我用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编译器生成的代码中看不到这些。
我错过了什么?
答案 0 :(得分:3)
这会准备调用函数__main
的参数,这可能会执行C程序所需的所有初始设置
andl $-16, %esp
subl $16, %esp
call ___main
这会准备参数并调用函数_puts
。 LC0
是包含要打印的字符串的符号。
movl $LC0, (%esp)
call _puts
这将准备main
的返回值并返回
movl $0, %eax
leave
ret
答案 1 :(得分:3)
您的示例代码使用Intel
语法,而gcc的标准输出是AT&T
语法。您可以使用
gcc -S hellow.c -masm=intel
结果输出应该更加熟悉。
但是,如果编译器生成源代码,那么它看起来会有所不同,那么您将手工编写的内容。
如果为DOS编译,将使用int
,但即便如此,这些调用也将包含在C标准函数中,例如puts
。