如何使用可以用nasm编译的gcc生成汇编代码

How to generate assembly code with gcc that can be compiled with nasm

本问题已经有最佳答案,请猛点这里访问。

我试图将汇编语言作为一种爱好学习,并且经常使用gcc -S来产生汇编输出。这非常简单,但是我无法编译程序集输出。我很好奇这是否可以做到。我尝试使用-masm=intel同时使用标准程序集输出和intel语法。两者都不能使用nasm进行编译,也不能使用ld链接。

因此,我想问一下是否有可能生成汇编代码,然后可以对其进行编译。

更准确地说,我使用了以下C代码。

1
2
3
4
5
6
7
 >> 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获得的输出为:

1
2
3
4
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

的输出

编辑:

有人暗示我的问题已在另一个问题中解决;不幸的是,在测试了此处描述的方法之后,我无法生成nasm汇编格式。您可以在下面看到objconv的输出。
因此,我仍然需要您的帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
>>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的输出时我犯了一个错误。我应该跑步:

1
sed -i"s/align=1//g ; s/[a-z]*execute//g ; s/: *function//g;  /default *rel/d" csimp.asm

所有步骤都可以在bash脚本中压缩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#! /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警告:

1
 ld: warning: cannot find entry symbol _start; defaulting to 0000000000400080

以这种方式生成的可执行文件因分段错误消息而崩溃。非常感谢您的帮助。


n


n


有很多不同的汇编语言-每个CPU可能有多种可能的语法(例如"英特尔语法"," AT


n