我正在研究一些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
距离data SEGMENT
的基地址偏移量为0100h
,所以无论此时DS
寄存器的值是什么,在任何出现offset foo
的地方,它都会放入0100h
的值。例如,如果我们将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
寄存器将等于变量 value1 的偏移量(而不是其实际值)。偏移量是变量存储的内存段开头地址。偏移量通常相对于 ds
段(在您的情况下,ds
和 cs
寄存器指向同一个段)。
来自MASM程序员指南6.1(Microsoft宏汇编器)
The OFFSET Operator
An address constant is a special type of immediate operand that consists of an offset or segment value. The OFFSET operator returns the offset of a memory location, as shown here:
mov bx, OFFSET var ; Load offset address
For information on differences between MASM 5.1 behavior and MASM 6.1 behavior related to OFFSET, see Appendix A.
Since data in different modules may belong to a single segment, the assembler cannot know for each module the true offsets within a segment. Thus, the offset for var, although an immediate value, is not determined until link time.
仔细阅读后,最终值是在将目标代码“链接”以创建DLL / EXE之后确定的。在链接之前,您拥有的只是一个立即值,它表示从段基地址的偏移量。
偏移量基本上是指从片段点(也称为基准点)的距离。 例如,片段地址为0000,偏移量或逻辑地址为0100,则物理地址可以通过添加两个对来计算。 物理地址= 0000 + 0100 = 0100 这意味着我们所需的位置在0100的地址上。 类似地,如果片段地址为1DDD,偏移量为0100,则: 物理地址为:1DDD + 0100 = 1EDD
这意味着我们的目标是1EDD。
@data
而不是数字字面量,对吧?(不过这个例子很好用。) - Peter Cordes<<4
=左移1个十六进制数字。 - Peter Cordes