我正在查看 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的值的。

例如,如果我们改变DSdata段汇编是假设的基部以外的东西:

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,所以该段的基部指向DS03000h。这意味着,ds:[offset foo]指向地址03000h + 0100h其是相同02000h + 01100h,它指向bar

其他提示

它只是意味着符号的地址。这是一个有点像和运营商C,如果你是熟悉。

offset意味着si寄存器将等于变量的偏移值1 (不是其实际值)。偏移量是从其中变量被存储存储器段的开始地址。偏移通常相对于ds段(在你的情况dscs寄存器指向相同段)。

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空间,偏移是该空间内。

请参阅 http://en.wikipedia.org/wiki/Memory_segmentation

偏移基本上是从段点(也称为基准点)的距离。 例如段地址为0000和偏移或逻辑地址是0100然后物理地址可以通过将两对进行计数。 物理地址= 0000 + 0100 = 0100 意味着我们需要的位置是在0100的地址。 类似地,如果段地址是1DDD和偏移是0100,则: 物理地址是:1DDD + 0100 = 1EDD

意味着我们的目的地是1EDD。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top