汇编,将单个字节从寄存器写入内存会覆盖其他字节

Posted

技术标签:

【中文标题】汇编,将单个字节从寄存器写入内存会覆盖其他字节【英文标题】:Assembly, writing a single byte from register to memory overwrites other bytes 【发布时间】:2021-01-01 04:58:17 【问题描述】:

在 64 位 x86 汇编 nasm 中,如何将单个字节从寄存器移动到 .data 节中定义的内存位置?

我知道这行得通

global _main

section .data
quotient db 0x0, 0x0, 0x30, 0xa ; 3 digit + newline
remainder db 0x0, 0x0, 0x30, 0xa; 3 digit + newline

section .text

_main:
mov rax, 0x2000004
mov rdi, 1
mov rsi, quotient
mov rdx, 8
syscall ; outputs 0 /newline 0 /newline as expected

exit:
mov rax, 0x2000001
mov rdi, 0
syscall

我也知道你可以使用 byte 关键字设置单个字节

mov rbx, quotient ; move location of quotient into memory
mov [rbx], byte 0x31 ; change first byte to ascii '1'

这将按预期输出 1 0 /newline 0 /newline

但是假设我想将其设置为寄存器值

mov rbx, quotient ; move location of quotient into memory
mov r8, 0x31 ; set another register to ascii '1'
mov [rbx], r8 ; write the register value into memory

这确实输出 1,但它似乎会覆盖内存中的每个字节,因此换行符被删除。

我的问题是如何将单个“字节”从寄存器写入内存位置?

【问题讨论】:

您可能希望看到这个:wiki.cdot.senecacollege.ca/wiki/…。特别是要移动一个字节,您可以这样做mov [rbx], r8b 哦,谢谢,我从 64 位寄存器的文章中猜测您每次都将 8 个字节写入内存,并在寄存器名称后写一个字节后缀 b?但是,当我尝试使用 rcxb 为 rcx 之类的寄存器添加后缀时,nasm 给了我符号“rcxb”未定义,这是我的汇编程序有问题还是只有编号的寄存器才有这种能力? 正确。如果源是 64 位寄存器,则将完整的 64 位数据写入目标内存地址,覆盖您真正想要写入的一个字节之后的 7 个额外字节。 啊,我从谷歌搜索后缀的东西cs.brown.edu/courses/cs033/docs/guides/x64_cheatsheet.pdf 中找到了另一篇文章,似乎不同的寄存器后缀不同,可以从中选择不同的字节。所以 rcx 选择第一个字节变成 cl 【参考方案1】:

64 位寄存器包含 8 个字节,因此将寄存器写入内存通过

mov [rbx], r8

将 8 个字节移动到从 rbx 开始的内存位置

下表显示了如何将任何寄存器中的 1,2,4 字节写入内存

例如,从 r8 寄存器中写入一个字节(字节 0)将是

mov [rbx], r8b

rax 中的一个字节是

mov [rbx], al

参考:http://cs.brown.edu/courses/cs033/docs/guides/x64_cheatsheet.pdf

【讨论】:

以上是关于汇编,将单个字节从寄存器写入内存会覆盖其他字节的主要内容,如果未能解决你的问题,请参考以下文章

汇编语言 第三章 寄存器

汇编语言第三章——寄存器(内存访问)

汇编语言第三章总结

汇编语言第三章总结

汇编 debug调试

汇编指令机器码说明