Ассемблер - c-язык и мнемоника

Я написал простую программу на языке c, классический helloworld. Я хотел знать, как это выглядело, когда компилятор переводил его в ассемблерный код.

Я использую MinGW и команду:

gcc -S hellow.c

Когда я открыл этот файл, я ожидал, что он будет, по крайней мере, несколько похож на программу hello-world, написанную непосредственно на ассемблере, а именно:

jmp 115
db 'Hello world!$' (db = define bytes)
-a 115 
mov ah, 09 (09 for displaying strings ... ah = 'command register')
mov dx, 102 (adress of the string)
int 21
int 20

Вместо этого это выглядит так:

   .file    "hellow.c"

.def    ___main;    
.scl    2;  
.type   32; 
.endef
.section 
.rdata,"dr"
LC0:

.ascii "Hello world!\0"

.text
.globl  _main

.def    _main;  
.scl    2;  
.type   32; 
.endef
_main:
 LFB6:

.cfi_startproc
pushl   %ebp

.cfi_def_cfa_offset 8

.cfi_offset 5, -8
movl    %esp, %ebp

.cfi_def_cfa_register 5
andl    $-16, %esp
subl    $16, %esp
call    ___main
movl    $LC0, (%esp)
call    _puts
movl    $0, %eax
leave

.cfi_restore 5

.cfi_def_cfa 4, 4
ret

.cfi_endproc
LFE6:

.def    _puts;  
.scl    2;  
.type   32; 
.endef

Я немного знаю о языке ассемблера, но я ДОЛЖЕН распознавать так называемые мнемоники, такие как ADD, POP, PUSH, MOV, JMP, INT и т. Д. Не могу увидеть большинство из них в коде, сгенерированном c-компилятором.

Что я не понял?

2 ответа

Ваш пример кода использует Intel синтаксис, в то время как стандартный вывод от gcc AT&T синтаксис. Вы можете изменить это с помощью

gcc -S hellow.c -masm=intel

Полученный результат должен выглядеть более знакомым.

Однако, если компилятор генерирует исходный код, он выглядит несколько иначе, чем то, что вы написали бы от руки.

int будет использоваться, если вы компилируете для DOS, но даже в этом случае эти вызовы будут заключены в стандартные функции C, например puts в этом случае.

Это подготавливает аргументы для вызова функции __main это, вероятно, делает все начальные настройки, необходимые для программы на C

andl    $-16, %esp
subl    $16, %esp
call    ___main

Это готовит аргументы и вызывает функцию _puts, LC0 является символом, который содержит строку для печати.

movl    $LC0, (%esp)
call    _puts

Это готовит возвращаемое значение main и возвращается

movl    $0, %eax
leave
ret
Другие вопросы по тегам