Что означает СМЕЩ в 16-битном ассемблерном коде?
Вопрос
Я рассматриваю пример ассемблерного кода для 16-битного реального режима.
Мне встретились строки:
mov bx, cs
mov ds, bx
mov si, OFFSET value1
pop es
mov di, OFFSET value2
что это делает?Что делает наличие там «СМЕЩ»?
Решение
Как говорят некоторые другие ответы, 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
.
Другие советы
Это просто означает адрес этого символа.Это немного похоже на оператор & в C, если вы с ним знакомы.
offset
Значит это si
регистр будет равен смещению переменной значение1 (не по фактической стоимости).Смещение — это адрес от начала сегмента памяти, в котором хранится переменная.Смещение обычно относительно ds
сегмент (в вашем случае ds
и cs
регистры указывают на один и тот же сегмент).
От Руководство программиста MASM 6.1 (Макросборщик Microsoft)
А КОМПЕНСИРОВАТЬ Оператор
Адресная константа — это особый тип непосредственного операнда, который состоит из значения смещения или сегмента.Оператор OFFSET возвращает смещение ячейки памяти, как показано здесь:
mov bx, OFFSET var ; Load offset address
Информацию о различиях между поведением MASM 5.1 и поведением MASM 6.1, связанным с OFFSET, см. в Приложении A.
Поскольку данные в разных модулях могут принадлежать одному сегменту, ассемблер не может знать для каждого модуля истинные смещения внутри сегмента.Таким образом, смещение для var, хотя и является непосредственным значением, не определяется до времени компоновки.
Если вы внимательно прочитаете, окончательное значение определяется после того, как вы «свяжете» свой объектный код для создания DLL/EXE.До связывания все, что у вас есть, — это непосредственное значение, которое представляет собой смещение от базового адреса сегмента.
В 16-битном режиме x86 адресное пространство не является плоским;вместо этого адреса состоят из смещения и «сегмента».«Сегмент» указывает на пространство размером 64 КБ, смещение находится в пределах этого пространства.
Смещение — это, по сути, расстояние от точки сегмента (также называемой базовой точкой).например, адрес сегмента — 0000, а смещение или логический адрес — 0100, тогда физический адрес можно посчитать путем сложения двух пар.Физический адрес = 0000+0100 = 0100 означает, что наше требуемое местоположение находится на адресе 0100.Аналогично, если адрес сегмента равен 1DDD, а смещение равно 0100, тогда:Физический адрес:1ДДД+0100=1ЕДД
Означает, что наш пункт назначения — 1EDD.