gcc生成32位的nasm汇编代码

使用gcc的时候只能产生masm的汇编代码。但是masm不是跨平台的,一般开发的时候都是用nasm进行汇编。但是gcc不能直接生成nasm汇编代码。这里记录了生成nasm汇编代码的方法。

答案来源于stackoverflow。此实验已经在Mac系统上已经尝试成功过。

生成中间文件

首先需要使用gcc生成中间文件:

1
gcc -fno-asynchronous-unwind-tables -s -O2 -c -o main.o main.c

如果你的电脑不是32位而是64位的话,gcc默认生成的是64位的中间代码,需要加上-m32来强制指定32位:

1
gcc -m32 -fno-asynchronous-unwind-tables -s -O2 -c -o main.o main.c

使用objconv转换为nasm汇编代码

然后需要使用objconv工具将中间文件转换为nasm汇编代码:

1
objconv -fnasm main.o main.asm

如果电脑上没有objconv工具,去这个网站Object file converter一栏下载,或者直接点击这个下载链接(如果还有效的话)。

下载下来之后解压,里面只有windows的可执行文件。如果想要在Mac或Linux上使用,解压source压缩包,进入解压后的source文件夹,运行build.sh编译,完成后会生成objconv文件(纯C++写的,不用安装其他库)。

去除错误的和不必要的代码

objconv会生成一些不必要的代码需要去除,主要是:

  • 使用global定义的函数名称标签
  • .SECTION一行中的executenoexecute,和(如果有需要的话)align=N语句
  • default rel
  • 空的段(如果你想的话)

下面是我写的一个perl小程序,可以自动化将c语言转为32位的nasm汇编语言,并去除多余代码(空的段不会去除):

 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
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/perl

use 5.010;
use utf8;
use strict;

sub ConvertC2Nasm{
    my $filename = shift;
    #$filename = chomp $filename;
    my $output_obj = $filename;
    my $output_asm = $filename;
    $output_obj=~s/c$/o/;
    $output_asm=~s/c$/asm/;
    system("gcc -m32 -fno-asynchronous-unwind-tables -s -O2 -c -o $output_obj $filename");
    system("objconv -fnasm $output_obj $output_asm");
    return $output_asm;
}

sub FixErrorInNasmFile{
    my $filename = shift;
    my @lines;
    open HANDLE, $filename or warn "$filename not exists";
    while(<HANDLE>){
        if($_=~/global .*$/){
            next;
        }
        if($_=~/default rel/){
            next;
        }
        if($_=~/SECTION/){
            $_=~s/execute//g;
            $_=~s/noexecute//g;
        }
        push @lines, $_;
    }
    close HANDLE;
    open HANDLE, ">$filename";
    print HANDLE @lines;
    close HANDLE;
}

while(@ARGV){
    my $filename = shift(@ARGV);
    say "file:$filename";
    FixErrorInNasmFile(ConvertC2Nasm($filename));
}
updatedupdated2023-06-082023-06-08