Как этот ассемблерный код x86 создает строку? - PullRequest
1 голос
/ 11 декабря 2019

Я изучаю язык ассемблера x86. Чтобы лучше понять, что происходит за кулисами создания строк, у меня есть пример программы, которая просто печатает строку. GCC создал следующую программу сборки, и у меня возникли проблемы с пониманием вывода компилятора:

Код сборки:

Dump of assembler code for function main:
   0x0000000000400596 <+0>: push   %rbp
   0x0000000000400597 <+1>: mov    %rsp,%rbp
   0x000000000040059a <+4>: sub    $0x10,%rsp
   0x000000000040059e <+8>: movq   $0x400668,-0x8(%rbp)
   0x00000000004005a6 <+16>:    mov    -0x8(%rbp),%rax
   0x00000000004005aa <+20>:    mov    %rax,%rsi
=> 0x00000000004005ad <+23>:    mov    $0x400675,%edi
   0x00000000004005b2 <+28>:    mov    $0x0,%eax
   0x00000000004005b7 <+33>:    callq  0x4004a0 <printf@plt>
   0x00000000004005bc <+38>:    mov    $0x0,%eax
   0x00000000004005c1 <+43>:    leaveq 
   0x00000000004005c2 <+44>:    retq 

C Код:

#include <stdio.h>
int main()
{
char *me = "abcdefghijkl";
printf("%s",me);
}

На концептуальном уровне я понимаю, что указатель стека вычитается для выделения памяти в стеке, а затем каким-то образом, , и у меня возникли проблемы с пониманиеммеханика , программа создает строку.

Может кто-нибудь помочь, пожалуйста? Спасибо.

1 Ответ

1 голос
/ 11 декабря 2019

Намного понятнее, если вы используете флаг -S для gcc, чтобы создать файл сборки для вашей программы (gcc -S asm.c). При этом создается файл asm.s:

        .file   "asm.c"
        .section        .rodata
.LC0:
        .string "abcdefghijkl"
.LC1:
        .string "%s"
        .text
        .globl  main
        .type   main, @function
main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $16, %rsp
        movq    $.LC0, -8(%rbp)
        movq    -8(%rbp), %rax
        movq    %rax, %rsi
        movl    $.LC1, %edi
        movl    $0, %eax
        call    printf
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
        .ident  "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)"
        .section        .note.GNU-stack,"",@progbits

Из этого вы можете видеть, что строка - это просто инициализированная память в разделе .rodata, которому назначена метка .LC0. Изменение этой памяти изменяет строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...