如何编译GCC生成的asm?
我正在玩一些ASM代码,有什么东西在困扰着我。
我编译这个:
#include <stdio.h> int main(int argc, char** argv){ printf("Hello World\n"); return 0; }
用gcc file.c -S -o file.S
生成一个很好的asm代码:
.cstring LC0: .ascii "Hello World\0" .text .globl _main _main: LFB3: pushq %rbp LCFI0: movq %rsp, %rbp LCFI1: subq $16, %rsp LCFI2: movl %edi, -4(%rbp) movq %rsi, -16(%rbp) leaq LC0(%rip), %rdi call _puts movl $0, %eax leave ret LFE3: .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support EH_frame1: .set L$set$0,LECIE1-LSCIE1 .long L$set$0 LSCIE1: .long 0x0 .byte 0x1 .ascii "zR\0" .byte 0x1 .byte 0x78 .byte 0x10 .byte 0x1 .byte 0x10 .byte 0xc .byte 0x7 .byte 0x8 .byte 0x90 .byte 0x1 .align 3 LECIE1: .globl _main.eh _main.eh: LSFDE1: .set L$set$1,LEFDE1-LASFDE1 .long L$set$1 LASFDE1: .long LASFDE1-EH_frame1 .quad LFB3-. .set L$set$2,LFE3-LFB3 .quad L$set$2 .byte 0x0 .byte 0x4 .set L$set$3,LCFI0-LFB3 .long L$set$3 .byte 0xe .byte 0x10 .byte 0x86 .byte 0x2 .byte 0x4 .set L$set$4,LCFI1-LCFI0 .long L$set$4 .byte 0xd .byte 0x6 .align 3 LEFDE1: .subsections_via_symbols
我的下一个问题是,我怎么编译这个输出,我可以让GCC为我做?
是的,你可以使用gcc编译你的asm代码。 使用-c进行编译,如下所示:
gcc -c file.S -o file.o
这将给出名为file.o的目标代码文件。 在上面的命令之后调用链接器执行以下命令:
gcc file.o -o file
gcc
可以使用汇编文件作为input,并根据需要调用汇编程序。 虽然有一个微妙之处:
- 如果文件名以“
.s
”(小写的“s”)结尾,则gcc
调用汇编程序。 - 如果文件名以“
.S
”(大写字母“S”)结尾,则gcc
在源文件上应用C预处理器(即,它识别#if
指令并replacemacros), 然后调用汇编程序。
所以,一般来说,你想要做这样的事情:
gcc -S file.c -o file.s gcc -c file.s
您可以将汇编代码embedded到普通的C程序中。 这是一个很好的介绍 。 使用适当的语法,你也可以告诉GCC你想与在C中声明的variables进行交互。下面的程序指示gcc:
- eax应该是foo
- ebx应该是吧
- 在执行汇编代码后,eax中的值应该存储在foo中
\ n
int main(void) { int foo = 10, bar = 15; __asm__ __volatile__("addl %%ebx,%%eax" :"=a"(foo) :"a"(foo), "b"(bar) ); printf("foo+bar=%d\n", foo); return 0; }
是的,gcc也可以编译汇编源代码。 或者,您可以调用as
,这是汇编程序。 (gcc只是一个使用启发式调用C编译器,C ++编译器,汇编器,链接器等的“驱动程序”程序。)
您可以使用gcc的后台汇编程序:
如果你有main.s文件。 你可以通过GCC
生成目标文件
# gcc -c main.s # as main.s -o main.o
检查这个链接,它会帮助你学习海湾合作委员会的一些binutils http://www.thegeekstuff.com/2017/01/gnu-binutils-commands/
nasm -f bin -o 2_hello 2_hello.asm