Что означает OFFSET в 16-битном ассемблере?

Я просматриваю пример кода сборки для 16-битного реального режима.

Я наткнулся на строки:

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

что это делает? Что означает наличие «OFFSET»?


person Without Me It Just Aweso    schedule 03.11.2009    source источник


Ответы (6)


Как говорится в некоторых других ответах, ключевое слово 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.

person Nathan Fellman    schedule 03.11.2009
comment
Откуда 2000h? Вы знаете, основываясь на некоторых других не показанных вещах, что это основа сегмента? Обычно вы бы использовали @data вместо числового литерала, верно? (Однако это хорошо работает для примера.) - person Peter Cordes; 04.08.2018
comment
@PeterCordes Сегмент 2000h должен быть 200h (та же проблема с 3000h), если он хочет соответствовать описанию. Значение сегмента 200 было бы произвольно выбрано в качестве примера с абсолютным значением для ясности (а не @data) - person Michael Petch; 04.08.2018
comment
@MichaelPetch: хороший улов. Я также вернул в комментарий линейный адрес 2000h, как напоминание о том, что используются значения сегментного регистра <<4 = слева на 1 шестнадцатеричный разряд. - person Peter Cordes; 04.08.2018

Это просто означает адрес этого символа. Это немного похоже на оператор & в C, если вы с ним знакомы.

person copumpkin    schedule 03.11.2009

offset означает, что регистр si будет равен смещению переменной value1 (а не ее фактическому значению). Смещение — это адрес от начала сегмента памяти, где хранится переменная. Смещение обычно относится к сегменту ds (в вашем случае регистры ds и cs указывают на один и тот же сегмент).

person Alexey Kalmykov    schedule 03.11.2009

В 16-битном режиме x86 адресное пространство не является плоским; вместо этого адреса состоят из смещения и «сегмента». «Сегмент» указывает на пространство размером 64 КБ, смещение находится в пределах этого пространства.

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

person Erich Kitzmueller    schedule 03.11.2009

Из Руководство программиста MASM 6.1 (Microsoft Macro Assembler)

Оператор OFFSET

Константа адреса — это особый тип непосредственного операнда, который состоит из значения смещения или сегмента. Оператор OFFSET возвращает смещение ячейки памяти, как показано здесь:

    mov     bx, OFFSET var  ; Load offset address

Для получения информации о различиях между поведением MASM 5.1 и поведением MASM 6.1, связанных со смещением, см. Приложение A.

Поскольку данные в разных модулях могут принадлежать одному сегменту, ассемблер не может знать для каждого модуля истинные смещения внутри сегмента. Таким образом, смещение для var, хотя и является непосредственным значением, не определяется до времени компоновки.

Если вы внимательно читаете, окончательное значение определяется после того, как вы «связываете» свой объектный код для создания DLL/EXE. Перед связыванием все, что у вас есть, — это непосредственное значение, которое представляет собой смещение от базового адреса сегмента.

person Community    schedule 03.08.2018
comment
По возможности не публикуйте изображения текста — вместо этого публикуйте сам текст. - person CertainPerformance; 04.08.2018

Смещение — это в основном расстояние от точки сегмента (также называемой базовой точкой). например, адрес сегмента равен 0000, а смещение или логический адрес равен 0100, тогда физический адрес можно подсчитать, добавив две пары. Физический адрес = 0000+0100=0100 Означает, что требуемое местоположение находится по адресу 0100. Точно так же, если адрес сегмента равен 1DDD, а смещение равно 0100, тогда: Физический адрес: 1DDD+0100=1EDD

Означает, что наш пункт назначения 1EDD.

person user2961595    schedule 06.11.2013