我正在玩一些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为我做这个吗?
答案 0 :(得分:76)
是的,您可以使用gcc编译您的asm代码。使用-c进行编译,如下所示:
gcc -c file.S -o file.o
这将给出名为file.o的目标代码文件。 要调用链接器,请执行以下命令:
gcc file.o -o file
答案 1 :(得分:45)
gcc
可以使用程序集文件作为输入,并根据需要调用汇编程序。但是有一个微妙之处:
.s
”(小写的's')结尾,则gcc
会调用汇编程序。.S
”结尾(大写“S”),则gcc
在源文件上应用C预处理器(即它识别#if
和gcc -S file.c -o file.s
gcc -c file.s
等指令。替换宏),然后在结果上调用汇编程序。所以,总的来说,你想做这样的事情:
{{1}}
答案 2 :(得分:10)
您可以将汇编代码嵌入到普通的C程序中。这是一个很好的introduction。使用适当的语法,您还可以告诉GCC您想要与C中声明的变量进行交互。下面的程序指示gcc:
\ 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;
}
答案 3 :(得分:3)
是的,gcc还可以编译汇编源代码。或者,您可以调用as
,这是汇编程序。 (gcc只是一个“驱动程序”程序,它使用启发式方法来调用C编译器,C ++编译器,汇编器,链接器等。)
答案 4 :(得分:3)
您可以使用GAS,它是gcc的后端汇编程序:
答案 5 :(得分:2)
如果你有main.s文件。
您可以按GCC
和as
# gcc -c main.s
# as main.s -o main.o
检查此链接,它将帮助您了解GCC的一些binutils http://www.thegeekstuff.com/2017/01/gnu-binutils-commands/
答案 6 :(得分:0)
nasm -f bin -o 2_hello 2_hello.asm