1

我用c语言写了一个简单的程序,经典的helloworld。我想知道编译器将它翻译成汇编代码时的样子。

我使用 MinGW 和命令:

gcc -S hello.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 编译器生成的代码中看不到很多这些。

我误会了什么?

4

2 回答 2

3

这准备了调用函数的参数,该函数__main可能完成 C 程序所需的所有初始设置

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

这准备了参数并调用 function _putsLC0是一个包含要打印的字符串的符号。

movl    $LC0, (%esp)
call    _puts

这准备了返回值main并返回

movl    $0, %eax
leave
ret
于 2013-09-12T13:41:18.227 回答
3

您的示例代码使用Intel 语法,而 gcc 的标准输出是AT&T语法。您可以通过使用更改它

gcc -S hellow.c -masm=intel

生成的输出应该看起来更熟悉。

但是,如果编译器生成源代码,那么它看起来会大不相同,那么您将手动编写。

如果您为 DOS 编译将int使用 ,但即便如此,这些调用仍将包装在 C 标准函数中,就像puts在这种情况下一样。

于 2013-09-12T14:01:28.087 回答