C代码转Windows x64汇编后,如何生成可执行文件?
如何将Windows x64汇编代码生成可执行文件
我尝试把一段C代码转换成Windows x64汇编时遇到大量错误,用AI工具也没成功完成转换,最终得到了一段汇编代码,想知道怎么把这段汇编代码生成可执行文件。
原C代码
#include <stdio.h> #define abs(z) (z > 0 ? (z) : -(z)) #define minimumDistance 4 #define charOffset 60 int main() { int radius = 15; int size = 2 * radius + 1; for (int y=0; y<size; y++) { int deltaY = abs(y - radius); for (int x=0; x<size; x++) { int deltaX = abs(x - radius); int dist = deltaX + deltaY; if (dist > minimumDistance) putchar(dist + charOffset); else putchar(' '); } putchar(10); } return 0; }
得到的汇编代码
main: push rbp mov rbp, rsp sub rsp, 32 mov DWORD PTR [rbp-12], 15 mov eax, DWORD PTR [rbp-12] add eax, eax add eax, 1 mov DWORD PTR [rbp-16], eax mov DWORD PTR [rbp-4], 0 jmp .L2 .L7: mov eax, DWORD PTR [rbp-4] sub eax, DWORD PTR [rbp-12] mov edx, eax neg edx cmovns eax, edx mov DWORD PTR [rbp-20], eax mov DWORD PTR [rbp-8], 0 jmp .L3 .L6: mov eax, DWORD PTR [rbp-8] sub eax, DWORD PTR [rbp-12] mov edx, eax neg edx cmovns eax, edx mov DWORD PTR [rbp-24], eax mov edx, DWORD PTR [rbp-24] mov eax, DWORD PTR [rbp-20] add eax, edx mov DWORD PTR [rbp-28], eax cmp DWORD PTR [rbp-28], 4 jle .L4 mov eax, DWORD PTR [rbp-28] add eax, 60 mov edi, eax call putchar jmp .L5 .L4: mov edi, 32 call putchar .L5: add DWORD PTR [rbp-8], 1 .L3: mov eax, DWORD PTR [rbp-8] cmp eax, DWORD PTR [rbp-16] jl .L6 mov edi, 10 call putchar add DWORD PTR [rbp-4], 1 .L2: mov eax, DWORD PTR [rbp-4] cmp eax, DWORD PTR [rbp-16] jl .L7 mov eax, 0 leave ret
生成可执行文件的两种方法
方法一:使用MinGW-w64工具链
MinGW-w64可以直接编译Intel语法的汇编代码,并自动链接C标准库:
- 安装MinGW-w64,确保
gcc命令在系统PATH中。 - 将汇编代码保存为
circle.asm。 - 打开命令提示符,进入文件所在目录,执行:
执行完成后会生成gcc -masm=intel circle.asm -o circle.execircle.exe,直接运行即可看到输出。
方法二:使用微软ML64汇编器(Visual Studio自带)
原汇编代码采用的是Linux平台的SysV x64调用约定,需要调整为Windows x64约定(用RCX传递第一个参数),再进行汇编链接:
- 打开Visual Studio的x64 Native Tools Command Prompt。
- 修改汇编代码,添加必要的段声明、外部函数引用,并修正调用约定:
.model flat, C .stack 4096 extern putchar:proc main: push rbp mov rbp, rsp sub rsp, 32 mov DWORD PTR [rbp-12], 15 mov eax, DWORD PTR [rbp-12] add eax, eax add eax, 1 mov DWORD PTR [rbp-16], eax mov DWORD PTR [rbp-4], 0 jmp .L2 .L7: mov eax, DWORD PTR [rbp-4] sub eax, DWORD PTR [rbp-12] mov edx, eax neg edx cmovns eax, edx mov DWORD PTR [rbp-20], eax mov DWORD PTR [rbp-8], 0 jmp .L3 .L6: mov eax, DWORD PTR [rbp-8] sub eax, DWORD PTR [rbp-12] mov edx, eax neg edx cmovns eax, edx mov DWORD PTR [rbp-24], eax mov edx, DWORD PTR [rbp-24] mov eax, DWORD PTR [rbp-20] add eax, edx mov DWORD PTR [rbp-28], eax cmp DWORD PTR [rbp-28], 4 jle .L4 mov eax, DWORD PTR [rbp-28] add eax, 60 mov ecx, eax ; 替换EDI为RCX,符合Windows x64调用约定 call putchar jmp .L5 .L4: mov ecx, 32 call putchar .L5: add DWORD PTR [rbp-8], 1 .L3: mov eax, DWORD PTR [rbp-8] cmp eax, DWORD PTR [rbp-16] jl .L6 mov ecx, 10 call putchar add DWORD PTR [rbp-4], 1 .L2: mov eax, DWORD PTR [rbp-4] cmp eax, DWORD PTR [rbp-16] jl .L7 mov eax, 0 leave ret .end main - 保存修改后的代码为
circle.asm,执行以下命令:
完成后会得到ml64 /c circle.asm ; 汇编生成目标文件circle.obj link circle.obj /subsystem:console /defaultlib:msvcrt.lib ; 链接生成可执行文件circle.exe,运行即可。
内容的提问来源于stack exchange,提问作者lalaland
相关产品推荐
相关产品推荐

