You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将rustc生成的x86汇编代码汇编为可执行文件并调试?

问题:汇编Rustc生成的x86汇编代码并生成带调试信息的可执行文件

我在汇编rustc编译器生成的x86汇编代码时遇到困难,尝试多种方法均无法生成可执行文件。代码本身很简单,但生成的汇编无法正常执行。

我尝试了三种方法:

  • 通过rustc生成汇编代码后,再用rustc汇编该代码;
  • 编译为LLVM字节码,再转为LLVM x86汇编,尝试用clang、rustc或gcc编译;
  • 使用as和ld工具,虽能生成目标文件,但无法链接为可执行文件。

所有步骤中,x86汇编代码均可正常生成,但无法将其汇编/链接为可执行文件。

关键需求:汇编过程需包含调试信息,因为我需要将其在GDB中调试,用于我的毕业论文。

测试代码

假设我有文件main.rs,代码如下:

pub fn main() {
    let mut j = 0;
    for i in 0..10 {
        j = j + 100;
        if i % 2 == 0 {
            j = j - 1;
        } else {
            j = j + 1;
        }
    }
}

尝试的方法及错误

方法1:用rustc生成汇编后再用rustc汇编

执行命令:

$ rustc --target=x86_64-unknown-linux-gnu --emit=asm -o main.s main.rs
$ rustc main.s

出现大量错误:

error: unknown character escape: `b`
   --> your_code.s:381:11
    |
381 |     .asciz    "\b\000\000\000\000\000\000\000\b\000\000\000\000\000\000"
    |                 ^ unknown character escape
...
error: expected item, found `.`
 --> your_code.s:1:2
  |
1 |     .text
  |     ^ expected item

方法2(及方法3):用as+ld或clang/gcc编译

执行命令:

$ as -o main.o main.s
$ ld -o main main.o

链接时出现未定义引用错误:

ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
ld: main.o: in function `std::rt::lang_start':
main.aaccb3f0a8cfdec6-cgu.0:(.text._ZN3std2rt10lang_start17h10f5244e46882c73E+0x23): undefined reference to `std::rt::lang_start_internal'
ld: main.o: in function `core::ops::function::FnOnce::call_once':
main.aaccb3f0a8cfdec6-cgu.0:(.text._ZN4core3ops8function6FnOnce9call_once17h90749210ed415b5cE+0x1f): undefined reference to `_Unwind_Resume'
...
ld: main.o:(.data.DW.ref.rust_eh_personality[DW.ref.rust_eh_personality]+0x0): undefined reference to `rust_eh_personality'

解决方案

一、正确生成带调试信息的汇编并编译为可执行文件

Rust生成的汇编包含大量Rust标准库依赖和特定汇编语法,直接用rustc汇编或裸as+ld会因缺少依赖、语法不兼容失败,正确步骤如下:

步骤1:生成带调试信息的汇编代码

要保留调试信息,生成汇编时需添加-g参数:

rustc --target=x86_64-unknown-linux-gnu -g --emit=asm -o main.s main.rs

该命令会生成包含DWARF调试信息的汇编文件main.s。

步骤2:用rustc链接汇编代码(解决方法1的错误)

不能直接用rustc main.s——rustc会把.s文件当成Rust源码处理,而非汇编。正确做法是让rustc调用汇编器并自动链接标准库:

rustc --target=x86_64-unknown-linux-gnu -g main.s -o main

此命令会调用系统as汇编器处理main.s,再链接Rust标准库和启动代码,最终生成带调试信息的可执行文件main。

替代方案:用clang/gcc汇编+rustc链接(解决方法2的错误)

若想用clang/gcc汇编,可先生成目标文件(保留调试信息):

clang -c -g main.s -o main.o

再用rustc完成链接(rustc知晓如何正确处理Rust依赖):

rustc --target=x86_64-unknown-linux-gnu main.o -o main

二、在GDB中调试汇编代码

生成带调试信息的可执行文件后,直接启动GDB:

gdb ./main

常用调试命令:

  • break main::main:在Rust的main函数处打断点(自动对应到汇编代码位置)
  • disassemble:查看当前函数的汇编代码
  • stepi:单步执行一条汇编指令
  • info registers:查看寄存器状态
  • list:查看对应Rust源码(因保留调试信息,GDB可关联源码与汇编)

若想直接调试汇编入口,可打断点到_start:

break _start
run

内容的提问来源于stack exchange,提问作者kush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 03:39:59