web-dev-qa-db-fra.com

Que signifie OFFSET dans le code d'assemblage 16 bits?

Je passe par un exemple de code d'assemblage pour le mode réel 16 bits.

Je suis tombé sur les lignes:

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

qu'est-ce que ça fait? À quoi sert "OFFSET"?

Comme le disent certaines des autres réponses, le mot clé offset fait référence au décalage par rapport au segment dans lequel il est défini. Notez cependant que les segments peuvent se chevaucher et que le décalage dans un segment peut être différent dans un autre segment. Par exemple, supposons que vous ayez le segment suivant en mode réel

data SEGMENT USE16 ;# at segment 0200h, linear address 2000h

    org 0100h
    foo db 0

    org 01100h
    bar db 0

data ENDS

L'assembleur voit que foo est à l'offset 0100h à partir de la base de data SEGMENT, donc partout où il voit offset foo il mettra la valeur 0100h, quelle que soit la valeur de DS à l'époque.

Par exemple, si nous changeons DS en autre chose que la base du segment data, l'assembleur suppose:

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

Dans le deuxième exemple, DS est 0300h, donc la base du segment pointé par DS est 03000h. Cela signifie que ds:[offset foo] pointe vers l'adresse 03000h + 0100h qui est identique à 02000h + 01100h, qui pointe vers bar.

20
Nathan Fellman

Cela signifie simplement l'adresse de ce symbole. C'est un peu comme l'opérateur & en C, si vous êtes familier avec cela.

9
copumpkin

offset signifie que le registre si sera égal au décalage de la variable valeur1 (pas à sa valeur réelle). Le décalage est l'adresse du début du segment de mémoire où la variable est stockée. Le décalage est généralement relatif au segment ds (dans votre cas, les registres ds et cs pointent vers le même segment).

3
Alexey Kalmykov

De Guide du programmeur MASM 6.1 (Microsoft Macro Assembler)

L'opérateur [~ # ~] [~ # ~] Opérateur

Une constante d'adresse est un type spécial d'opérande immédiat qui se compose d'un décalage ou d'une valeur de segment. L'opérateur OFFSET renvoie l'offset d'un emplacement mémoire, comme illustré ici:

    mov     bx, OFFSET var  ; Load offset address

Pour plus d'informations sur les différences entre le comportement MASM 5.1 et le comportement MASM 6.1 liés au décalage, consultez l'annexe A.

Étant donné que les données de différents modules peuvent appartenir à un seul segment, l'assembleur ne peut pas connaître pour chaque module les vrais décalages au sein d'un segment. Ainsi, le décalage pour var, bien qu'une valeur immédiate, n'est pas déterminé avant le temps de liaison.

Si vous lisez attentivement, la valeur finale est déterminée après avoir "lié" votre code objet pour créer une DLL/EXE. Avant la liaison, tout ce que vous avez est une valeur immédiate qui représente le décalage par rapport à l'adresse de base du segment.

2
user10058428

Le décalage est essentiellement la distance du point de segment (également appelé point de référence). par exemple, l'adresse de segment est 0000 et l'adresse de décalage ou logique est 0100, alors l'adresse physique peut être comptée en ajoutant les deux paires. Adresse physique = 0000 + 0100 = 0100 Signifie que notre emplacement requis est sur l'adresse de 0100. De même si l'adresse de segment est 1DDD et le décalage est 0100 alors: L'adresse physique est: 1DDD + 0100 = 1EDD

Signifie que notre destination est 1EDD.

1
user2961595

En mode x86 16 bits, l'espace d'adressage n'est pas plat; au lieu de cela, les adresses sont composées d'un décalage et d'un "segment". Le "segment" pointe vers un espace de 64 Ko, le décalage se trouve dans cet espace.

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

1