【问题标题】:assembly language - c-language and mnemonics汇编语言 - c 语言和助记符
【发布时间】:2013-09-16 22:17:45
【问题描述】:

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

我误会了什么?

【问题讨论】:

  • 有时你的代码会消失,但当你试图学习这种方式时,最好尝试使用优化 -O2 或任何你的编译器想要的东西进行编译。如果没有优化,就会有更多的开销和代码需要尝试理解。不过,有时您的死代码会被删除,但您必须了解这意味着什么……

标签: c assembly mnemonics


【解决方案1】:

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

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

这会准备参数并调用函数_puts。 LC0 是一个符号,包含要打印的字符串。

movl    $LC0, (%esp)
call    _puts

这准备了main的返回值并返回

movl    $0, %eax
leave
ret

【讨论】:

  • 基本上,C 程序使用 C 标准运行时库进行 I/O,而您的原始程序集似乎使用 DOS 中断或其他东西。
【解决方案2】:

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

进行更改
gcc -S hellow.c -masm=intel

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

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

int 将在您为 DOS 编译时使用,但即便如此,这些调用仍将包装在 C 标准函数中,如本例中的 puts。

【讨论】:

    猜你喜欢
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多