从C到汇编

从C到汇编,c,assembly,C,Assembly,有人能解释一下吗,我有一个C语言的程序,我能把它转换成汇编语言吗?如果是,怎么做?编译器就是这样做的 编译器将C程序编译为机器语言,这是机器程序的二进制表示形式。当一个人想要编写机器语言时,他/她用汇编语言编写,汇编语言被翻译成二进制机器语言 汇编代码只是二进制机器语言的一种可读形式 C程序: $ cat test.c #include <stdio.h> int main(int argc, char **argv) { int a = 11+12; print

有人能解释一下吗,我有一个C语言的程序,我能把它转换成汇编语言吗?如果是,怎么做?

编译器就是这样做的

编译器将C程序编译为机器语言,这是机器程序的二进制表示形式。当一个人想要编写机器语言时,他/她用汇编语言编写,汇编语言被翻译成二进制机器语言

汇编代码只是二进制机器语言的一种可读形式

C程序:

$ cat test.c 
#include <stdio.h>

int main(int argc, char **argv) {
    int a = 11+12;
    printf("a = %d\n", a);
    return 0;
}
拆卸它:

$ objdump -d test.o

test.o:     file format elf32-i386


Disassembly of section .text:

00000000 <main>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 e4 f0                and    $0xfffffff0,%esp
   6:   83 ec 20                sub    $0x20,%esp
   9:   c7 44 24 1c 17 00 00    movl   $0x17,0x1c(%esp)
  10:   00 
  11:   b8 00 00 00 00          mov    $0x0,%eax
  16:   8b 54 24 1c             mov    0x1c(%esp),%edx
  1a:   89 54 24 04             mov    %edx,0x4(%esp)
  1e:   89 04 24                mov    %eax,(%esp)
  21:   e8 fc ff ff ff          call   22 <main+0x22>
  26:   b8 00 00 00 00          mov    $0x0,%eax
  2b:   c9                      leave  
  2c:   c3                      ret    
$objdump-d test.o
test.o:文件格式elf32-i386
第节的分解。正文:
00000000 :
0:55推力%ebp
1:89 e5 mov%esp,%ebp
3:83 e4 f0和$0xfffffff0,%esp
6:83 ec 20子$0x20,%esp
9:c7 44 24 1c 17 00动产$0x17,0x1c(%esp)
10:   00 
11:b8 00 mov$0x0,%eax
16:8b 54 24 1c mov 0x1c(%esp),%edx
1a:89 54 24 04 mov%edx,0x4(%esp)
1e:89 04 24 mov%eax,(%esp)
21:e8 fc ff呼叫22
26:b8 00 mov$0x0,%eax
2b:c9离开
2c:c3 ret

如果您使用gcc,您可以根据页面执行
gcc-O2-S-c foo.c
,以获得可读形式的输出程序集。

使用gcc,您可以使用
-S
选项:

gcc -O2 -S myfile.c
这里也可以使用大多数其他选项(如
-O2
)来确定生成哪种类型的汇编代码


但是,请注意,这只是公开编译器无论如何都要经历的中间步骤(不是生成程序集源文件,而是它所表示的机器代码)。通过汇编程序传递此代码后的最终结果与直接编译为机器代码没有任何区别。

您的编译器应该有这样做的选项。例如,对于gcc,您可以使用-S选项。举个简单的例子:

// test.c

#include <stdio.h>

int
main ()
{
  printf ("hello, world\n");
  return 0;
}

大多数编译器都有一些选项来生成程序集列表和二进制文件。 在Visual Studio中,您可以在文件属性的“代码生成”部分找到它。
有了gcc,您可以使用-S开关(大写字母S)

最后,如果您有一个二进制文件,那么可以使用objdump-S(大写字母S)。

既然您提到了Dev-C++,那么值得一提的是,
-S
标志也在这里起作用。假设使用Windows,Dev-C++仍会将输出命名为.exe,但结果不会是可执行文件,因此只需将扩展名更改为.txt或其他任何文件,即可在您选择的编辑器中读取。在“项目>项目选项>参数>编译器或工具>编译器选项”下添加选项/标志。

例如,我正在使用dev cpp,在哪里可以找到此选项?查看项目的编译器/代码生成器选项,搜索类似“生成程序集列表”的内容。我确信dev cpp具有生成程序集输出的选项(类似于gcc)。我不知道dev cpp对于中间输出是否有相同的钩子,但我不认为您真的需要这些钩子来满足您的要求+1@Anders亚伯:如果我需要特别的东西?例如pdp-11?使用一个交叉编译器,为您想要的arch生成代码。您能给我一个例子吗,提前谢谢,它到底是什么意思?为什么是-O2?当然,你不需要优化,这样你就能理解事情了。如果我需要特别的东西?比如pdp-11?哈哈!好吧令人惊叹的!我找了大约半个小时,昨天整个晚上都在找这个。终于到了!不,我在哪里发现您必须将其重命名为文档格式!该死的,我被迷住了!非常感谢,先生!
// test.c

#include <stdio.h>

int
main ()
{
  printf ("hello, world\n");
  return 0;
}
.file   "test.c"
    .section    .rodata
.LC0:
    .string "hello, world"
    .text
.globl main
    .type   main, @function
main:
    leal    4(%esp), %ecx
    andl    $-16, %esp
    pushl   -4(%ecx)
    pushl   %ebp
    movl    %esp, %ebp
    pushl   %ecx
    subl    $4, %esp
    movl    $.LC0, (%esp)
    call    puts
    movl    $0, %eax
    addl    $4, %esp
    popl    %ecx
    popl    %ebp
    leal    -4(%ecx), %esp
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
    .section    .note.GNU-stack,"",@progbits