【问题标题】:What does OFFSET in 16 bit assembly code mean?16位汇编代码中的OFFSET是什么意思?
【发布时间】:2010-12-12 18:48:04
【问题描述】:

我正在浏览一些 16 位实模式的示例汇编代码。

我遇到过以下问题:

    mov    bx, cs
    mov    ds, bx
    mov    si, OFFSET value1
    pop    es
    mov    di, OFFSET value2

这是在做什么?那里有“偏移”有什么作用?

【问题讨论】:

    标签: assembly x86 masm x86-16 16-bit


    【解决方案1】:

    正如其他一些答案所说,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 放在时间。

    例如,如果我们将 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
    

    在第二个例子中DS0300h,所以DS 指向的段的基是03000h。这意味着ds:[offset foo] 指向地址03000h + 0100h02000h + 01100h 相同,后者指向bar

    【讨论】:

    • 2000h 来自哪里?你知道基于其他一些未显示的东西,它是 seg 基础吗?通常你会使用@data 而不是数字文字,对吧? (不过,这很适合作为示例。)
    • @PeterCordes Segment 2000h 应该是 200h,(与 3000h 相同的问题)如果它想匹配描述。为清楚起见,段值 200 将被任意选择为具有绝对值的示例(而不是 @data)
    • @MichaelPetch:很好。我也在评论中放回了 2000h 线性地址,以提醒使用段寄存器值 <<4 = 左移 1 个十六进制数字。
    【解决方案2】:

    它只是表示该符号的地址。如果你熟悉的话,它有点像 C 中的 & 运算符。

    【讨论】:

      【解决方案3】:

      offset 表示si 寄存器将等于变量value1 的偏移量(而不是其实际值)。偏移量是存储变量的内存段开头的地址。偏移量通常与 ds 段相关(在您的情况下,dscs 寄存器指向同一段)。

      【讨论】:

        【解决方案4】:

        在 x86 16bit 模式下,地址空间不是平坦的;相反,地址由偏移量和“段”组成。 “段”指向一个 64K 的空间,偏移量在该空间内。

        http://en.wikipedia.org/wiki/Memory_segmentation

        【讨论】:

          【解决方案5】:

          来自MASM Programmer's Guide 6.1(微软宏汇编程序)

          偏移量运算符

          地址常量是一种特殊类型的立即操作数,由偏移量或段值组成。 OFFSET 运算符返回内存位置的偏移量,如下所示:

              mov     bx, OFFSET var  ; Load offset address
          

          有关 MASM 5.1 行为和 MASM 6.1 行为与 OFFSET 相关的差异的信息,请参阅附录 A。

          由于不同模块中的数据可能属于单个段,因此汇编器无法知道每个模块在段内的真实偏移量。因此,var 的偏移量虽然是立即值,但直到链接时间才确定。

          如果您仔细阅读,最终值是在您“链接”您的目标代码以创建 DLL/EXE 后确定的。在链接之前,您所拥有的只是一个立即值,它表示距段基地址的偏移量。

          【讨论】:

          • 尽可能不要发布文字图片 - 而是发布实际文字。
          【解决方案6】:

          偏移量基本上是与线段点(也称为基准点)的距离。 例如段地址是 0000 并且偏移量或逻辑地址是 0100 那么物理地址可以通过将两对相加来计算。 物理地址 = 0000+0100=0100 表示我们需要的位置在0100的地址上。 同样,如果段地址为 1DDD 且偏移量为 0100,则: 物理地址为:1DDD+0100=1EDD

          表示我们的目的地是 1EDD。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-07-31
            • 2018-06-13
            • 1970-01-01
            • 1970-01-01
            • 2010-12-12
            • 1970-01-01
            相关资源
            最近更新 更多