16位汇编代码中的OFFSET是什么意思?
题
我正在查看 16 位实模式的一些示例汇编代码。
我遇到过这样的情况:
mov bx, cs
mov ds, bx
mov si, OFFSET value1
pop es
mov di, OFFSET value2
这是在做什么?那里有“OFFSET”有什么作用?
解决方案
由于一些其他的答案就是说,offset
关键字是指从在其被确定的段相关的偏移。但是请注意,该段可以重叠,且在一个数据段的偏移可以是在另一个不同的段。举例来说,假设您在实模式下段
data SEGMENT USE16 ;# at segment 0200h, linear address 2000h
org 0100h
foo db 0
org 01100h
bar db 0
data ENDS
汇编器看到该foo
是在从0100h
的基本偏移data SEGMENT
,所以无论它看到offset foo
它会把值0100h
,不管当时的DS
的值的。
例如,如果我们改变DS
比data
段汇编是假设的基部以外的东西:
mov ax, 200h ; in some assemblers you can use @data for the seg base
mov ds, ax
mov bx, offset foo ; bx = 0100h
mov byte ptr [bx], 10 ; foo = 10
mov ax, 300h
mov ds, ax
mov bx, offset foo ; bx = 0100h
mov byte ptr [bx], 10 ; bar = 10, not foo, because DS doesn't match what we told the assembler
在第二个例子是DS
0300h
,所以该段的基部指向DS
是03000h
。这意味着,ds:[offset foo]
指向地址03000h + 0100h
其是相同02000h + 01100h
,它指向bar
。
其他提示
它只是意味着符号的地址。这是一个有点像和运营商C,如果你是熟悉。
offset
意味着si
寄存器将等于变量的偏移值1 (不是其实际值)。偏移量是从其中变量被存储存储器段的开始地址。偏移通常相对于ds
段(在你的情况ds
和cs
寄存器指向相同段)。
从 MASM 程序员指南 6.1 (微软宏汇编器)
这 抵消 操作员
地址常量是一种特殊类型的立即操作数,由偏移量或段值组成。OFFSET 运算符返回内存位置的偏移量,如下所示:
mov bx, OFFSET var ; Load offset address
有关与 OFFSET 相关的 MASM 5.1 行为和 MASM 6.1 行为之间的差异的信息,请参阅附录 A。
由于不同模块中的数据可能属于单个段,因此汇编器无法知道每个模块在段内的真实偏移量。因此,var 的偏移量虽然是立即值,但直到链接时才确定。
如果您仔细阅读,最终值是在您“链接”目标代码以创建 DLL/EXE 后确定的。在链接之前,您拥有的只是一个立即值,它表示距段基地址的偏移量。
在86 16位模式中,地址空间是不平坦的;相反,地址组成的偏移和“段”的。的“段”指向一个64K空间,偏移是该空间内。
偏移基本上是从段点(也称为基准点)的距离。 例如段地址为0000和偏移或逻辑地址是0100然后物理地址可以通过将两对进行计数。 物理地址= 0000 + 0100 = 0100 意味着我们需要的位置是在0100的地址。 类似地,如果段地址是1DDD和偏移是0100,则: 物理地址是:1DDD + 0100 = 1EDD
意味着我们的目的地是1EDD。