Modalità di indirizzamento in linguaggio assembly (IA-32 NASM)

Dato che le risorse web su questo argomento sono scarse, inizierò, a beneficio delle ricerche future, elencando le modalità degli indirizzi per IA-32 Assembly Language (NASM) e poi seguirò una breve domanda.

  1. Registro di indirizzamento
    • mov eax, ebx: copia ciò che è in ebx in eax
    • mov esi, var: Copia l’indirizzo di var (ad esempio 0x0040120e) in esi
  2. Indirizzamento immediato (il secondo operando è una costante immediata)
    • mov bx, 20: 16-bit register bx ottiene il valore effettivo 20
  3. Indirizzamento diretto della memoria (carica direttamente dalla memoria attraverso un indirizzo specificato)
    • mov ax, [1000h]: carica un object a 2 byte dal byte all’indirizzo 4096 (0x1000 in esadecimale) in un registro a 16 bit chiamato ‘ax’
    • mov [1000h], ax: la memoria all’indirizzo 1000h ottiene il valore dell’ascia
  4. Indirizzamento offset diretto (come 3, basta usare aritmetica per modificare l’indirizzo)
    • mov al, [byte_tbl + 2]
  5. Registra indiretto (accede alla memoria usando gli indirizzi memorizzati nei registri)
    • mov ax, [di]: copia il valore all’indirizzo di memoria specificato da di, in ax
    • mov dword [eax], var1: copia il valore in var1 nello slot di memoria specificato da eax

Si prega di notare che quanto sopra è per NASM. Per MASM / TASM dovresti usare “mov esi, OFFSET foo” per ottenere l’indirizzo, mentre “mov esi, foo” e “mov esi, [foo]” otterrebbero entrambi il valore (credito a @Michael).

Quindi, sulla mia domanda. È in relazione a un esempio in fondo alla pagina 29 del seguente tutorial: http://www.tutorialspoint.com/assembly_programming/assembly_tutorial.pdf

In pratica elenca il codice seguente come esempio di indirizzamento indiretto della memoria.

MY_TABLE TIMES 10 DW 0 ; Allocates 10 words (2 bytes) each initialized to 0 MOV EBX, [MY_TABLE] ; Effective Address of MY_TABLE in EBX MOV [EBX], 110 ; MY_TABLE[0] = 110 ADD EBX, 2 ; EBX = EBX +2 MOV [EBX], 123 ; MY_TABLE[1] = 123 

Le mie domande:

  1. “MOV EBX, [MY_TABLE]” non dovrebbe essere “MOV EBX, MY_TABLE”, poiché vogliamo mettere l’indirizzo della tabella in EBX, non il valore stesso?
  2. Sicuramente è MY_TABLE [2] che è uguale a 123 alla fine, non MY_TABLE [1]?

  1. Nella syntax NASM, quella istruzione dovrebbe essere MOV EBX, MY_TABLE . Ciò che MOV EBX, [MY_TABLE] dovrebbe fare è caricare i primi 4 byte situati in MY_TABLE in EBX . Un’altra alternativa sarebbe utilizzare LEA , come in LEA EBX, [MY_TABLE] .

  2. In questo caso il tutorial è giusto. MY_TABLE è definito come un array di parole. Una parola su x86 è di 2 byte, quindi il secondo elemento di MY_TABLE si trova in MY_TABLE + 2 .

Quel tutorial non è nemmeno un codice NASM valido. Per i link a guide / risorse / manuali x86 che non fanno schifo, vedi il tag wiki x86 qui su SO.

MOV [EBX], 110 non si assemblerà perché nessuno degli operandi implica una dimensione dell’operando . (Penso che anche MASM non lo assemblerà, ma alcuni assembler cattivi come emu8086 hanno una dimensione di operando di default per istruzioni come questa.) mov word [ebx], 110 farebbe un archivio a 16 bit.

MOV EBX, [MY_TABLE] si assembla ma carica le prime 2 parole dalla tabella. mov ebx, MY_TABLE metterà l’indirizzo in un registro.