如何在x86_64汇编(NASM)中修改变量值?
问题分析与解决
你的问题出在两个核心点:
8字节寄存器覆盖过多内存
你用mov [text], rax将8字节的rax寄存器内容写入内存,但text是用db定义的单字节序列,这会直接覆盖text起始的8个字节,导致原字符串第3到第8位的字符被清零。终端输出时空字符不会显示,原字符串第9位的o会紧跟在He之后,最终形成Heorld!的结果。小端字节序导致字符顺序错误(尝试
mov word [text], "He"时)
x86_64采用小端字节序,寄存器数据写入内存时,低字节会被放在低地址。当你写mov word [text], "He",NASM会将"He"解析为16位值0x4865(H对应0x48,e对应0x65,字符顺序对应寄存器高位到低位),写入内存后,text[0]会是0x65(e),text[1]会是0x48(H),最终得到eH...的错误顺序。
修复方案
方案1:逐字节修改(最直观可靠)
直接分别修改text的前两个字节,完全避免覆盖其他内容:
section .data text db "Hello, World!",10 section .text global _start _start: ; 初始输出 mov rax, 1 mov rdi, 1 mov rsi, text mov rdx, 14 syscall ; 逐字节修改前两个字符 mov byte [text], 'H' mov byte [text+1], 'e' ; 再次输出 mov rax, 1 mov rdi, 1 mov rsi, text mov rdx, 14 syscall ; 退出程序 mov rax, 60 mov rdi, 0 syscall
方案2:16位寄存器配合小端序调整
如果想用16位操作一次修改两个字节,需要调整字符串字面量的顺序适配小端规则:
section .data text db "Hello, World!",10 section .text global _start _start: ; 初始输出 mov rax, 1 mov rdi, 1 mov rsi, text mov rdx, 14 syscall ; 用"eH"作为立即数,小端存储后得到"He"的正确顺序 mov ax, "eH" mov word [text], ax ; 再次输出 mov rax, 1 mov rdi, 1 mov rsi, text mov rdx, 14 syscall ; 退出程序 mov rax, 60 mov rdi, 0 syscall
另外,记得移除你代码中多余的syscall(在mov [text], rax之后的那个),它会调用无效的系统调用,可能引发不必要的错误。
内容的提问来源于stack exchange,提问作者liveno
相关产品推荐
相关产品推荐

