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

两段功能相同的汇编代码跨编译器报错及64位转换问题咨询

x86汇编跨编译环境适配问题解决方案

两段代码分别对应64位Linux系统调用规范(使用syscall指令、64位寄存器)和32位Linux系统调用规范(使用int 0x80指令、32位寄存器),跨环境运行报错本质是模式不匹配,以下是针对性解决方法:

1. 64位代码在32位环境报错("Instructions not supported in 32-bit mode")

原因

第一段代码使用了64位专属寄存器(rax/rdi/rsi等)和syscall指令,对应环境默认以32位模式编译,无法识别64位指令。

解决方法

将代码修改为32位系统调用规范:

section .data
    msg db "Hello world!", 0ah
    len equ $ - msg

section .text
    global _start

_start:
    mov eax, 4    ; 32位sys_write系统调用号
    mov ebx, 1    ; stdout文件描述符
    mov ecx, msg  ; 字符串内存地址
    mov edx, len  ; 字符串长度
    int 0x80      ; 触发内核调用
    mov eax, 1    ; 32位sys_exit系统调用号
    mov ebx, 0    ; 程序退出码
    int 0x80

2. 32位代码在64位环境报错("signal: bad system call (core dumped)")

原因

64位环境下执行int 0x80会触发32位系统调用,但寄存器传递规则、系统调用号与64位syscall完全不同,参数传递错误导致非法系统调用。

解决方法

切换为64位系统调用规范:

section .data
    msg db 'Hello, world!',0xa
    len equ $ - msg

section .text
    global _start

_start:
    mov rax, 1    ; 64位sys_write系统调用号
    mov rdi, 1    ; stdout文件描述符
    mov rsi, msg  ; 字符串内存地址
    mov rdx, len  ; 字符串长度
    syscall       ; 触发内核调用
    mov rax, 60   ; 64位sys_exit系统调用号
    mov rdi, 0    ; 程序退出码
    syscall

3. 添加bits 64后报错("64-bit unsigned relocation zero-extended from 32 bits"、"Segmentation fault")

原因

仅添加bits 64开启64位模式,但代码仍混用32位寄存器、int 0x80调用方式,32位地址重定位在64位模式下会被零扩展为错误的64位地址,同时系统调用参数传递完全失效,触发段错误。

解决方法

彻底切换到64位系统调用规范:

  • 替换所有32位寄存器为对应64位寄存器(eax→rax,ebx→rdi,ecx→rsi,edx→rdx)
  • 替换int 0x80为64位专属的syscall指令
  • 使用64位系统调用号(sys_write为1,sys_exit为60)
    修改后的代码与上述64位环境适配代码一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 05:07:01