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

r11寄存器出现异常行为的技术排查请求

x86-64汇编中r11寄存器被意外修改的原因分析

问题重现

你编写了用于打印寄存器状态的汇编调试代码,测试逻辑如下:

call _getDebugString
mov r9, debugString
call _printTextSafe
call _getDebugString
mov r9, debugString
call _printTextSafe
mov r11, -24
call _getDebugString
mov r9, debugString
call _printTextSafe
call _getDebugString
mov r9, debugString
call _printTextSafe
call _exit

执行后发现r11寄存器每次在_printTextSafe调用后被修改为582,输出结果:

rax = 1 rbx = -2 rcx = 3 rdx = -4 rsi = 5 rdi = -6 r8 = 7 r9 = -8 r10 = 9 r11 = 0 r12 = 11 r13 = -12 r14 = 13 r15 = -14
rax = 1 rbx = -2 rcx = 3 rdx = -4 rsi = 5 rdi = -6 r8 = 7 r9 = 4202678r10 = 9 r11 = 582 r12 = 11 r13 = -12 r14 = 13 r15 = -14
rax = 1 rbx = -2 rcx = 3 rdx = -4 rsi = 5 rdi = -6 r8 = 7 r9 = 4202678r10 = 9 r11 = -24 r12 = 11 r13 = -12 r14 = 13 r15 = -14
rax = 1 rbx = -2 rcx = 3 rdx = -4 rsi = 5 rdi = -6 r8 = 7 r9 = 4202678r10 = 9 r11 = 582 r12 = 11 r13 = -12 r14 = 13 r15 = -14

原因分析

  • r11是x86-64调用约定中的易失性寄存器:在System V AMD64(Linux/macOS通用)调用约定里,r11属于调用者保存寄存器——被调用函数(比如_printTextSafe)无需保存和恢复r11的值。如果你的代码需要在调用其他函数后保留r11的内容,必须由你自己在调用前将r11压栈保存,调用完成后再出栈恢复。
  • _printTextSafe内部的syscall指令会直接修改r11:如果_printTextSafe底层调用了系统调用(如write),syscall指令执行时会将当前RFLAGS寄存器的值存入r11,这个过程会直接覆盖r11原有内容。你看到的582就是调用syscall前RFLAGS的十进制数值。
  • 测试流程遗漏了r11的保存步骤:从输出可以看到,直接修改r11后调用_getDebugString,输出的r11值是正确的(-24),说明_getDebugString确实正确保存了它自身用到的寄存器;但调用_printTextSafe后,r11被修改,而你没有在调用_printTextSafe前保存r11,因此再次调用_getDebugString时,r11已经是被修改后的数值。

另外,r9寄存器同样被修改,这也符合调用约定——r9作为第3个参数寄存器,同样属于易失性寄存器,_printTextSafe会随意使用它而不恢复。

解决方法

  • 在调用_printTextSafe前,手动保存需要保留的易失性寄存器,调用后恢复:
    call _getDebugString
    push r11          ; 保存r11
    push r9           ; 若需要保留r9也可保存
    mov r9, debugString
    call _printTextSafe
    pop r9            ; 恢复r9
    pop r11           ; 恢复r11
    call _getDebugString
    
  • 不推荐修改_printTextSafe让它保存恢复r11,这会违反x86-64调用约定的规范,导致代码兼容性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:30:43