Valgrind运行小型x86汇编程序提示Unrecognised instruction错误
问题原因
你在x86_64(amd64)环境下执行默认的汇编、链接流程时,as和ld会生成64位ELF格式可执行文件。代码中使用的int $0x80是32位x86架构的软中断系统调用方式,Linux内核提供了向后兼容层,允许64位程序直接执行该指令完成系统调用,因此脱离Valgrind直接运行时程序可以正常退出。
报错中提到的未处理指令字节0xCD 0x80就是int $0x80对应的机器码。Valgrind的二进制翻译引擎VEX在amd64指令集翻译模式下,没有实现对int 0x80指令的翻译支持——该指令不属于amd64架构的原生系统调用方式,VEX遇到无法识别翻译的指令时就会抛出SIGILL非法指令错误,终止程序运行。
解决方法
二选一即可:
方案1:改用amd64原生语法编写汇编(64位环境推荐)
amd64架构使用syscall指令触发系统调用,系统调用号、传参寄存器规则和32位x86完全不同,修改后的代码如下:.global _start .text _start: movq $60, %rax # exit系统调用号,64位下为60,对应32位的1 movq $0, %rdi # 第一个参数:退出码,64位使用rdi传递首参数,对应32位的ebx syscall # 原生系统调用指令,替代int 0x80保持原有的汇编、链接命令不变即可,生成的64位程序可以被Valgrind正常识别分析,不会触发指令错误。
方案2:构建纯32位x86可执行文件
如果需要保留32位汇编写法,汇编和链接时增加参数指定生成32位目标文件即可,注意提前安装系统的32位运行库、Valgrind 32位支持组件:as --32 demo.s -o demo.o ld -m elf_i386 demo.o -o demo生成的32位ELF文件运行时,Valgrind会自动切换到x86 32位翻译模式,该模式原生支持
int 0x80指令,可正常运行分析。
内容的提问来源于stack exchange,提问作者Michael Federczuk
相关产品推荐
相关产品推荐

