x86汇编中解引用MOV操作的栈覆写效果疑问
指令执行逻辑与结果说明
逐指令执行拆解
- 执行
LEA RAX, [RBP – 0x40]:直接将目标栈位置的地址(即RBP-0x40的计算值)存入RAX寄存器,此时RAX的值等于目标内存单元的起始地址,过程不读取内存的原有内容。 - 执行
MOV EDX, 0xFFFF5520:遵循x86-64架构的通用规则,所有对32位通用寄存器的写入操作,会自动将对应64位寄存器的高32位清零。执行完成后,64位宽度的RDX寄存器整体值为0x00000000FFFF5520,其中RDX的最低8位(即DL寄存器)的值为0x20。 - 执行
MOV [RAX], DL:这条指令的源操作数是8位宽度的DL寄存器,因此默认采用字节宽度的内存操作,仅将DL的值写入RAX指向的1个内存字节,不对其他内存字节做任何修改。
核心问题解答
栈位置最终存储值
x86架构采用小端序存储规则:多字节数值的最低有效字节,会存储在该数值起始地址对应的最低地址位置。
结合给定初始条件([RBP – 0x40]起始位置存储的初始值为0xFFFF7710),其原始存储分布为:
- 地址
[RBP-0x40](即RAX指向的目标地址):存储初始值的最低有效字节0x10 - 地址
[RBP-0x41]~[RBP-0x43]:依次存储初始值的其余高位字节0x77、0xFF、0xFF
执行完字节写入操作后,仅把[RBP-0x40]地址处的原有0x10替换为0x20,其余高位字节完全保留初始值。重新拼装后,该位置的最终存储值为**0xFFFF7720**。
其余两个选项的错误逻辑:
0x00000020:错误认为字节写入会覆盖整个多字节内存单元,实际上高位字节未被修改,不会被清零。0xFFFFFF20:错误对写入的字节值做高位符号扩展,普通MOV指令在执行内存写入时不会触发符号扩展操作,仅按指定宽度写入对应字节。
最后一条指令的覆写范围
最后一条MOV [RAX], DL仅覆写RAX指向地址对应的1个字节(即目标栈位置存储值的最低有效字节),不会覆盖该位置存储的全部多字节内容。
注意:x86指令的内存操作宽度由操作数类型决定:如果源操作数是8位寄存器(如DL),默认执行字节宽度操作;如果要完成4字节宽度的写入,需要在指令中显式标注操作宽度(如
MOV DWORD PTR [RAX], EDX),无法通过8位寄存器DL完成全位置的内容覆写。
内容的提问来源于stack exchange,提问作者Federico Jensen
相关产品推荐
相关产品推荐

