向内存地址添加偏移量

Posted

技术标签:

【中文标题】向内存地址添加偏移量【英文标题】:Adding an offset to a memory address 【发布时间】:2019-05-02 04:55:35 【问题描述】:

我有一些这样的代码(emu8086)

data segment
    str1 db "hello"
    len dw 4h
data ends

code segment
    ...
    ...
    mov si, offset str1
    lea di, [si + len]
code ends

我希望这会使 di 指向 DS:0004 的地址,但是生成的实际指令是 LEA DI, [SI] + 021h

如果相反,我使用:

lea di, [si + 4]

然后它按预期工作。

如何使第一个版本以与第二个类似的方式工作?

【问题讨论】:

如果有人能写出更好的标题,请继续。 【参考方案1】:

您的“预期”4 来自哪里?如果它来自len dw 4h 的内容,那么你需要一个负载,比如add si, [len]

lea访问内存的内容。

x86 没有带有内存源的复制和添加功能,因此您必须在带有寄存器目标的“破坏性”add 或仅使用寄存器 + 汇编进行数学运算的 lea 之间进行选择时间常数

【讨论】:

所以如果我理解正确的话,我不能用lea来加载si+len的地址。相反,我必须使用add 指令。 您能详细说明lea di, [si + len] 是如何减少为LEA DI, [SI] + 021h 的吗?是不是因为len位于021h? @Rishav:这是一种奇怪的语法,通常你会写成lea di, [si + 21h],但是如果你在反汇编中看到它,那是因为offset len = 21h。如果您将[si + len] 用作任何其他指令的内存操作数,您将在len + si 处访问内存,例如使用si 作为字节偏移量的C 数组索引。 谢谢。是的,那个语法是由emu8086而不是我产生的。 @Rishav:emu8086 很奇怪,并且有一些奇怪的行为。就像mov [si], 1 一样,汇编而不是给出关于不明确的操作数大小的错误。它只是选择一个默认的操作数大小,无论是字节还是单词,我忘记了!

以上是关于向内存地址添加偏移量的主要内容,如果未能解决你的问题,请参考以下文章

内存地址,知道dll的偏移量和基地址如何获取内存地址来设置值

为啥 xxd 和 objdump 的内存地址或偏移量不同?

C中的内存对齐:返回地址中的偏移量是如何考虑的?

汇编语言程序设计中,段寄存器的内容和偏移量合起来是内存地址,

PE查找文件偏移地址

内存对齐计算方法(偏移量)