Вопрос

Я рассматриваю пример ассемблерного кода для 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 КБ, смещение находится в пределах этого пространства.

Видеть http://en.wikipedia.org/wiki/Memory_segmentation

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top