如何在Linux上从C源代码生成nasm可编译汇编代码?

How to generate a nasm compilable assembly code from c source code on Linux?

测试平台是32位Linux。

基本上,我知道gcc可用于生成Intel和At&T风格
汇编代码,但似乎您不能直接使用nasm / tasm进行编译
生成的英特尔样式汇编代码gcc。

我正在Windows和Linux平台上都进行项目分析asm代码,因此我想如果它们都可以由独立于平台的汇编程序(如nasm \ yasm)进行编译,那么我可以拥有更轻松的时间...

所以我的问题是如何在Linux上从c源代码生成nasm可编译汇编代码?


我发现这是反汇编目标文件而不是使用gcc生成的汇编代码的更好方法。

  • 首先,从您的源代码生成一个目标文件:

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

    -fno-asynchronous-unwind-tables:不要生成不必要的部分,例如.eh_frame

    -O2进行了优化,因此asm并不可怕。 (可选)使用-Os(大小超过速度)或-O3(包括自动矢量化在内的全面优化)。您还可以调整CPU,并使用-march=native-march=haswell-march=znver1(Zen)使用它支持的扩展

    -s:制作较小的可执行文件(带状)

    -c -o main.o:编译但不链接,生成一个名为main.o的目标文件

  • 使用objconv生成nasm代码:

    1
    objconv -fnasm main.o

    结果将存储在main.asm中。

  • 结果将非常接近Nasm语法。但是,您可能需要进行一些细微调整,以消除警告/错误。只需尝试使用Nasm进行编译

    1
    nasm -f elf32 main.asm

    并手动修复错误/警告。例如:

    • .SECTION行中删除align=Nexecute / noexecute字。
    • global声明中删除文本: function
    • 删除default rel
    • 如果需要,请删除空白部分
  • 使用gcc链接Nasm在步骤3中生成的结果main.o

    1
    gcc main.o

    您也可以使用ld链接它,但是要困难得多。


  • 如果您很懒:
    https://github.com/diogovk/c2nasm

    那里有一个脚本可以自动执行Babken Vardanyan的建议。


    这是不使用objconv的方法

    1
    ndisasm -u <(objdump -j .text -d main.o | cut -d: -f2 | cut -d$'\\t' -f 2 | perl -ne 'next if /file/; s/\\s+//g; print' | xxd -r -p)