我正在浏览一些16位实模式的汇编代码。
我遇到了这些问题:
mov bx, cs
mov ds, bx
mov si, OFFSET value1
pop es
mov di, OFFSET value2
这是做什么的? “OFFSET”有什么作用?
答案 0 :(得分:19)
正如其他一些答案所说,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
。
答案 1 :(得分:8)
它只表示该符号的地址。这有点像& C中的运算符,如果您熟悉它。
答案 2 :(得分:3)
offset
表示si
寄存器将等于变量 value1 的偏移量(而不是其实际值)。偏移量是存储变量的内存段开头的地址。偏移量通常相对于ds
段(在您的情况下为ds
且cs
个寄存器指向同一段)。
答案 3 :(得分:2)
来自MASM Programmer's Guide 6.1(Microsoft宏汇编程序)
OFFSET 运算符
地址常量是一种特殊类型的立即数,它由一个偏移量或段值组成。 OFFSET运算符返回存储位置的偏移量,如下所示:
server.php
有关MASM 5.1行为和与OFFSET相关的MASM 6.1行为之间的区别的信息,请参阅附录A。
由于不同模块中的数据可能属于单个段,因此汇编器无法为每个模块知道段内的真实偏移量。因此,var的偏移量虽然是立即值,但直到链接时间才确定。
如果您仔细阅读,最终值将在您“链接”目标代码以创建DLL / EXE之后确定。链接之前,您所拥有的只是一个立即数,该值代表与段的基地址的偏移量。
答案 4 :(得分:1)
在x86 16位模式下,地址空间不平坦;相反,地址由偏移和“段”组成。 “段”指向64K空间,偏移量在该空间内。
答案 5 :(得分:1)
偏移基本上是距离分段点(也称为基准点)的距离。 例如,段地址是0000,偏移或逻辑地址是0100,那么可以通过添加两对来计算物理地址。 物理地址= 0000 + 0100 = 0100 表示我们所需的位置在0100的地址上。 同样,如果段地址为1DDD且偏移量为0100,则: 物理地址是:1DDD + 0100 = 1EDD
表示我们的目的地是1EDD。