我正在尝试学习汇编语言作为一种爱好,我经常使用gcc -S
来生成汇编输出。这非常简单,但我无法编译程序集输出。我只是好奇这是否可以完成。我尝试使用标准汇编输出和使用-masm=intel
的英特尔语法。两者都不能与nasm
编译并链接到ld
。如何使用gcc生成汇编代码,可以使用nasm编译
因此我想问一下是否可以生成汇编代码,然后才能编译。
更确切地说,我使用了下面的C代码。
>> cat csimp.c
int main (void){
int i,j;
for(i=1;i<21;i++)
j= i + 100;
return 0;
}
生成组件与gcc -S -O0 -masm=intel csimp.c
和试图与nasm -f elf64 csimp.s
和链路与ld -m elf_x86_64 -s -o test csimp.o
进行编译。我从nasm得到的输出如下:
csimp.s:1: error: attempt to define a local label before any non-local labels
csimp.s:1: error: parser: instruction expected
csimp.s:2: error: attempt to define a local label before any non-local labels
csimp.s:2: error: parser: instruction expected
这很可能是由于装配语法破坏造成的。我希望,我将能够解决这个问题,而不必手动纠正gcc -S
输出
编辑:
我得到了我的问题是另外一个问题解决的hint;不幸的是,在测试了那里描述的方法之后,我无法制作出组装格式。您可以在下面看到objconv
的输出。 因此,我仍然需要你的帮助。
>>cat csimp.asm
; Disassembly of file: csimp.o
; Sat Jan 30 20:17:39 2016
; Mode: 64 bits
; Syntax: YASM/NASM
; Instruction set: 8086, x64
global main: ; **the ':' should be removed !!!**
SECTION .text ; section number 1, code
main: ; Function begin
push rbp ; 0000 _ 55
mov rbp, rsp ; 0001 _ 48: 89. E5
mov dword [rbp-4H], 1 ; 0004 _ C7. 45, FC, 00000001
jmp ?_002 ; 000B _ EB, 0D
?_001: mov eax, dword [rbp-4H] ; 000D _ 8B. 45, FC
add eax, 100 ; 0010 _ 83. C0, 64
mov dword [rbp-8H], eax ; 0013 _ 89. 45, F8
add dword [rbp-4H], 1 ; 0016 _ 83. 45, FC, 01
?_002: cmp dword [rbp-4H], 20 ; 001A _ 83. 7D, FC, 14
jle ?_001 ; 001E _ 7E, ED
pop rbp ; 0020 _ 5D
ret ; 0021 _ C3
; main End of function
SECTION .data ; section number 2, data
SECTION .bss ; section number 3, bss
表观解决方案:
我清理objconv
输出的时候犯了一个错误。我应该已经运行:
sed -i "s/align=1//g ; s/[a-z]*execute//g ; s/: *function//g; /default *rel/d" csimp.asm
所有步骤可以在bash
脚本
#! /bin/bash
a=$(echo $1 | sed "s/\.c//") # strip the file extension .c
# compile binary with minimal information
gcc -fno-asynchronous-unwind-tables -s -c ${a}.c
# convert the executable to nasm format
./objconv/objconv -fnasm ${a}.o
# remove unnecesairy objconv information
sed -i "s/align=1//g ; s/[a-z]*execute//g ; s/: *function//g; /default *rel/d" ${a}.asm
# run nasm for 64-bit binary
nasm -f elf64 ${a}.asm
# link --> see comment of MichaelPetch below
ld -m elf_x86_64 -s ${a}.o
凝结运行这段代码中,我得到了ld
警告:
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400080
以这种方式生成的可执行分段故障消息崩溃。我很感谢你的帮助。
输出被用于GNU汇编('as') ,你不使用它的任何特定原因?它将“只是工作”。不幸的是,'nasm'有不同的语法。 – Jester
我不知道这一点。我会尽力,谢谢你的回答。我很惊讶汇编语法不通用。 –
[如何从Linux的c源代码生成nasm可编译汇编代码?](http://stackoverflow.com/questions/20737947/how-to-generate-a-nasm-compilable-assembly-code- from-c-source-code-on-linux) –