Introduction
A Motorola 68000 instruction normally contains an operation, one or more operands, and a way of locating those operands. The addressing mode is the part that defines where an operand comes from or where a result goes.Una instrucción Motorola 68000 normalmente contiene una operación, uno o más operandos y una forma de localizar esos operandos. El modo de direccionamiento es la parte que define de dónde viene un operando o a dónde va el resultado.
move.w d0,d1
move.w (a0),d1
move.w #$1234,d1All three instructions use MOVE, but the source operand is different: one reads from a data register, one reads from memory pointed to by an address register, and one uses an immediate value encoded in the instruction stream.Las tres instrucciones usan MOVE, pero el operando fuente cambia: una lee desde un registro de datos, otra lee desde la memoria apuntada por un registro de dirección y otra usa un valor inmediato codificado dentro del flujo de instrucciones.
For Mega Drive reverse engineering, addressing modes are not syntax trivia. They reveal how code reaches variables, tables, structures, graphics data, hardware registers, stack data, and ROM resources.En ingeniería inversa de Mega Drive, los modos de direccionamiento no son un detalle de sintaxis. Revelan cómo el código llega a variables, tablas, estructuras, datos gráficos, registros de hardware, datos de pila y recursos de ROM.
68000 register refresher
Data registers D0-D7 are typically used for arithmetic, counters, temporary values, bit operations, and data manipulation.Los registros de datos D0-D7 suelen usarse para aritmética, contadores, valores temporales, operaciones de bits y manipulación de datos.
Address registers A0-A7 are usually used for pointers, memory addresses, arrays, structures, and stack access. A7 is the stack pointer.Los registros de dirección A0-A7 suelen usarse para punteros, direcciones de memoria, arrays, estructuras y acceso a la pila. A7 es el puntero de pila.
For the full register overview, read Registers and Data Types.Para el repaso completo de registros, lee Registros y tipos de datos.
Addressing mode notation
Motorola syntax and assembler dialects can vary slightly. The table below uses the notation style common across 68K Revival articles and many Mega Drive disassemblies.La sintaxis Motorola y los dialectos de ensamblador pueden variar ligeramente. La tabla siguiente usa la notación habitual en los artículos de 68K Revival y en muchos desensamblados de Mega Drive.
| Syntax | Name |
|---|---|
| Dn | Data Register DirectDirecto por registro de datos |
| An | Address Register DirectDirecto por registro de dirección |
| (An) | Address Register IndirectIndirecto por registro de dirección |
| (An)+ | Address Register Indirect with PostincrementIndirecto por registro de dirección con postincremento |
| -(An) | Address Register Indirect with PredecrementIndirecto por registro de dirección con predecremento |
| d16(An) | Address Register Indirect with DisplacementIndirecto por registro de dirección con desplazamiento |
| d8(An,Xn) | Address Register Indirect with IndexIndirecto por registro de dirección con índice |
| xxx.W | Absolute ShortAbsoluto corto |
| xxx.L | Absolute LongAbsoluto largo |
| d16(PC) | Program Counter RelativeRelativo al contador de programa |
| d8(PC,Xn) | PC Relative with IndexRelativo a PC con índice |
| #<data> | ImmediateInmediato |
Data Register Direct — Dn
move.w d0,d1
add.w d2,d0The operand lives directly inside a data register. No memory lookup is required, so this mode is common for temporary values, counters, arithmetic, and bit manipulation.El operando vive directamente dentro de un registro de datos. No hace falta leer memoria, así que este modo es habitual para valores temporales, contadores, aritmética y manipulación de bits.
Address Register Direct — An
move.l a0,a1
adda.l d0,a0Address registers usually contain pointers rather than ordinary game values. The 68000 also treats them differently in several instructions: MOVEA, ADDA, and SUBA exist specifically for address-register operations.Los registros de dirección suelen contener punteros más que valores normales del juego. Además, el 68000 los trata de forma distinta en varias instrucciones: MOVEA, ADDA y SUBA existen específicamente para operar con registros de dirección.
Copying one address register to another often suggests pointer setup, structure traversal, buffer selection, or resource loading.Copiar un registro de dirección a otro suele sugerir preparación de punteros, recorrido de estructuras, selección de buffers o carga de recursos.
Address Register Indirect — (An)
move.w (a0),d0A0 contains an address. The CPU reads the word stored at that address and places it into D0.A0 contiene una dirección. La CPU lee la word guardada en esa dirección y la coloca en D0.
A0 = $FF1000
$FF1000 -> 12 34
move.w (a0),d0
D0 = $1234This is one of the most important modes in reverse engineering because it usually means a register is acting as a pointer to data.Este es uno de los modos más importantes en ingeniería inversa porque normalmente significa que un registro está actuando como puntero a datos.
Address Register Indirect with Postincrement — (An)+
move.w (a0)+,d0The CPU reads from the address in A0, then advances A0 by the operand size.La CPU lee desde la dirección contenida en A0 y después avanza A0 según el tamaño del operando.
A0 = $2000
move.w (a0)+,d0
Read word at $2000
A0 becomes $2002- Reading arraysLeer arrays
- Walking tablesRecorrer tablas
- Copy loopsBucles de copia
- Resource streamsFlujos de recursos
- Decompression routinesRutinas de descompresión
- Sequential graphics dataDatos gráficos secuenciales
A repeated pattern like this strongly suggests a sequential copy, although the surrounding setup still matters.Un patrón repetido como este sugiere con fuerza una copia secuencial, aunque la preparación que lo rodea sigue siendo importante.
move.w (a0)+,(a1)+
dbra d0,.loopAddress Register Indirect with Predecrement — -(An)
move.l d0,-(sp)The address register is decremented first, then the access happens at the new address. This mode has a strong relationship with stack operations.El registro de dirección se decrementa primero y después el acceso ocurre en la nueva dirección. Este modo está muy relacionado con las operaciones de pila.
move.l d0,-(sp)
move.l a0,-(sp)
; ... routine work ...
move.l (sp)+,a0
move.l (sp)+,d0The first two instructions often save registers on the stack; the later postincrement reads can restore them. Recognizing this shape is useful when identifying routine prologues and epilogues.Las dos primeras instrucciones suelen guardar registros en la pila; las lecturas posteriores con postincremento pueden restaurarlos. Reconocer esta forma ayuda a identificar prólogos y epílogos de rutinas.
Address Register Indirect with Displacement — d16(An)
move.w 6(a0),d0The effective address is A0 plus a signed 16-bit displacement. In game code, this often indicates access to a field inside a structure.La dirección efectiva es A0 más un desplazamiento de 16 bits con signo. En código de juegos, esto suele indicar acceso a un campo dentro de una estructura.
Player structure (synthetic example)
+0 X position
+2 Y position
+4 Speed
+6 State
move.w 6(a0),d0In that synthetic structure, the instruction could mean read Player.State. Repeated offsets from the same address register are one of the strongest signs that you are looking at a structured object.En esa estructura sintética, la instrucción podría significar leer Player.State. Los offsets repetidos desde el mismo registro de dirección son una de las señales más fuertes de que estás mirando un objeto estructurado.
move.w 0(a0),d0
move.w 2(a0),d1
move.b 6(a0),d2Address Register Indirect with Index — d8(An,Xn)
move.w 0(a0,d0.w),d1Base address
+
Index register
+
Optional displacementIndexed addressing is extremely important for lookup tables, arrays, animation tables, object tables, and state tables.El direccionamiento indexado es muy importante para tablas de búsqueda, arrays, tablas de animación, tablas de objetos y tablas de estados.
A0 -> table start
D0 -> entry offset
move.w (a0,d0.w),d1The index may be a direct byte offset, a pre-scaled index, or an entry position transformed by nearby code. The original 68000 does not provide later 68020-style arbitrary scale factors such as *2, *4, or *8 inside the addressing mode. If scaling is needed, the game usually adjusts the index beforehand.El índice puede ser un offset directo en bytes, un índice preescalado o una posición de entrada transformada por código cercano. El 68000 original no ofrece factores de escala arbitrarios estilo 68020 como *2, *4 o *8 dentro del modo de direccionamiento. Si hace falta escalar, el juego suele ajustar el índice antes.
Absolute Short — xxx.W
Absolute short encodes a 16-bit absolute value, which the 68000 sign-extends when forming the address. On a 24-bit Mega Drive address bus, this can be useful for low memory or high mirrored RAM addresses, but it cannot represent arbitrary hardware addresses.El absoluto corto codifica un valor absoluto de 16 bits, que el 68000 extiende con signo al formar la dirección. En el bus de direcciones de 24 bits de Mega Drive, esto puede servir para memoria baja o RAM alta espejada, pero no representa direcciones de hardware arbitrarias.
Absolute Long — xxx.L
move.w ($C00004).l,d0Absolute long stores the full 32-bit address in the instruction stream. In Mega Drive code, this form is common when accessing memory-mapped hardware, RAM, ROM locations, or fixed global data.El absoluto largo guarda la dirección completa de 32 bits dentro del flujo de instrucciones. En código de Mega Drive, esta forma es habitual para acceder a hardware mapeado en memoria, RAM, posiciones de ROM o datos globales fijos.
Program Counter Relative — d16(PC)
lea table(pc),a0The address is calculated relative to the current Program Counter. This is useful for position-independent code, nearby tables, local constants, and lookup structures.La dirección se calcula en relación con el Program Counter actual. Esto resulta útil para código independiente de posición, tablas cercanas, constantes locales y estructuras de búsqueda.
In reverse engineering, PC-relative references often suggest that nearby data belongs closely to the routine using it: local tables, text, constants, pointer arrays, or resource metadata.En ingeniería inversa, las referencias relativas a PC suelen sugerir que los datos cercanos pertenecen a la rutina que los usa: tablas locales, texto, constantes, arrays de punteros o metadatos de recursos.
PC Relative with Index — d8(PC,Xn)
This combines the current program location, a small displacement, and an index register. It can be useful for table lookups located close to code. In some Mega Drive game code it appears less often than ordinary address-register indexed access, but it is still important to recognize.Este modo combina la ubicación actual del programa, un desplazamiento pequeño y un registro índice. Puede ser útil para consultas en tablas cercanas al código. En parte del código de juegos de Mega Drive aparece menos que el indexado normal con registros de dirección, pero sigue siendo importante reconocerlo.
Immediate — #<data>
move.w #$1234,d0
andi.w #$00FF,d0
cmpi.b #$10,d0Immediate data is encoded directly in the instruction stream. Immediate values often reveal constants, limits, masks, IDs, state values, hardware control values, and loop counts.El dato inmediato está codificado directamente dentro del flujo de instrucciones. Los valores inmediatos suelen revelar constantes, límites, máscaras, IDs, valores de estado, valores de control de hardware y contadores de bucle.
Effective Address
Motorola documentation often uses EA to mean Effective Address: the final operand location calculated by the CPU after applying the addressing mode.La documentación de Motorola suele usar EA para referirse a Effective Address, es decir, la ubicación final del operando calculada por la CPU después de aplicar el modo de direccionamiento.
Operand Size Matters
The suffix controls the size: .b is byte, .w is word, and .l is long word. This affects both the amount of data read or written and how postincrement/predecrement moves the address register.El sufijo controla el tamaño: .b es byte, .w es word y .l es long word. Esto afecta tanto a la cantidad de datos leídos o escritos como al movimiento del registro en postincremento/predecremento.
move.b (a0)+,d0 ; A0 normally advances by 1
move.w (a0)+,d0 ; A0 advances by 2
move.l (a0)+,d0 ; A0 advances by 4A7 has special byte behavior on the original 68000: byte postincrement or predecrement through the stack pointer adjusts by 2 instead of 1 so the stack remains word-aligned.A7 tiene un comportamiento especial con bytes en el 68000 original: el postincremento o predecremento de byte usando el puntero de pila ajusta 2 en vez de 1 para mantener la pila alineada a word.
Alignment Matters
The original 68000 requires word and long-word accesses to use even addresses. An odd-address word or long access can cause an address error.El 68000 original requiere que los accesos word y long word usen direcciones pares. Un acceso word o long en dirección impar puede provocar un error de dirección.
$FF1000 -> valid for word access
$FF1002 -> valid for word access
$FF1001 -> invalid for word accessThis matters during ROM hacking because structures are often aligned, pointer arithmetic must preserve alignment, and misreading a data size can make a real structure look nonsensical.Esto importa en romhacking porque las estructuras suelen estar alineadas, la aritmética de punteros debe preservar esa alineación y leer mal el tamaño de un dato puede hacer que una estructura real parezca absurda.
What Addressing Modes Tell You
Addressing modes rarely prove an interpretation by themselves, but they are excellent evidence. The same instruction mnemonic can point to very different behavior depending on how its operands are addressed.Los modos de direccionamiento rara vez prueban una interpretación por sí solos, pero son una evidencia excelente. El mismo mnemónico puede apuntar a comportamientos muy distintos según cómo se direccionen sus operandos.
move.w (a0)+,d0 ; often suggests a stream, array, table, or resource
move.w 8(a0),d0 ; often suggests a field inside an object or structure
move.w (a0,d0.w),d1 ; often suggests indexed table access
move.l d0,-(sp) ; often suggests register preservation
cmpi.w #$0010,d0 ; often suggests a limit, state, ID, or countRecognizing Structures from Addressing Modes
Repeated accesses relative to A0 suggest that A0 points to a structured object. Early in the analysis, avoid naming fields too aggressively. Start with offsets and sizes, then let behavior refine the meaning.Los accesos repetidos relativos a A0 sugieren que A0 apunta a un objeto estructurado. Al principio del análisis, evita nombrar campos demasiado pronto. Empieza con offsets y tamaños, y deja que el comportamiento precise el significado.
move.w 0(a0),d0
move.w 2(a0),d1
move.w 4(a0),d2
move.b 6(a0),d3
Object +0 -> unknown word
Object +2 -> unknown word
Object +4 -> unknown word
Object +6 -> unknown byte
; Later, after observing behavior:
Object +0 -> X position
Object +2 -> Y position
Object +4 -> speed
Object +6 -> stateArrays and Tables
add.w d0,d0
move.w (a0,d0.w),d1
lsl.w #2,d0
move.l (a0,d0.w),a1Doubling an index immediately before indexed addressing often suggests 2-byte entries. Shifting left by two before a long-word access may suggest 4-byte entries or pointers. This is one of the most useful ways to discover table entry sizes, but it still needs context.Duplicar un índice justo antes del direccionamiento indexado suele sugerir entradas de 2 bytes. Desplazar a la izquierda dos posiciones antes de un acceso long puede sugerir entradas de 4 bytes o punteros. Es una de las técnicas más útiles para descubrir tamaños de entrada, pero sigue necesitando contexto.
Pointer Tables
Games often calculate an index, read an offset or pointer, and then use that result to locate another resource. Addressing modes expose each step of that chain.Los juegos suelen calcular un índice, leer un offset o puntero y después usar ese resultado para localizar otro recurso. Los modos de direccionamiento hacen visible cada paso de esa cadena.
add.w d0,d0
move.w (a0,d0.w),d1
lea resources(pc),a1
adda.w d1,a1
movea.l a1,a2This example is synthetic. Its purpose is to show the relationship between index calculation, table lookup, and the address that is eventually used.Este ejemplo es sintético. Su objetivo es mostrar la relación entre el cálculo del índice, la consulta de una tabla y la dirección que finalmente se usa.
Addressing Memory-Mapped Hardware
The 68000 communicates with Mega Drive hardware through memory-mapped addresses. Absolute addressing may therefore mean hardware access rather than ordinary RAM access.El 68000 se comunica con el hardware de Mega Drive mediante direcciones mapeadas en memoria. Por eso, el direccionamiento absoluto puede significar acceso a hardware y no a RAM ordinaria.
move.w #$8004,($C00004).l ; VDP control port example
move.b #$00,($A11100).l ; Z80 bus request register exampleCommon examples include VDP ports, Z80 bus control, and I/O registers. This article only uses them to show the addressing pattern; the full memory map belongs in dedicated hardware and ROM-structure articles.Ejemplos habituales incluyen los puertos VDP, el control de bus del Z80 y registros de entrada/salida. Este artículo solo los usa para mostrar el patrón de direccionamiento; el mapa de memoria completo pertenece a artículos dedicados de hardware y estructura de ROM.
Common Mistakes
- Confusing the value in An with the data stored at (An).Confundir el valor de An con los datos almacenados en (An).
- Forgetting that (An)+ changes the register after access.Olvidar que (An)+ cambia el registro después del acceso.
- Forgetting that -(An) changes the register before access.Olvidar que -(An) cambia el registro antes del acceso.
- Ignoring operand size.Ignorar el tamaño del operando.
- Assuming an index register is an array index instead of a byte offset.Asumir que un registro índice es un índice de array en vez de un offset en bytes.
- Forgetting that displacements may be signed.Olvidar que los desplazamientos pueden tener signo.
- Confusing immediate data with memory addresses.Confundir datos inmediatos con direcciones de memoria.
- Treating every absolute address as RAM.Tratar toda dirección absoluta como RAM.
- Ignoring alignment.Ignorar la alineación.
- Forgetting A7 byte postincrement/predecrement behavior.Olvidar el comportamiento especial de A7 con byte en postincremento/predecremento.
- Confusing EA as Effective Address with EA as Electronic Arts.Confundir EA como Effective Address con EA como Electronic Arts.
Addressing Mode Quick Reference
Use this as a compact reading aid, not as a replacement for tracing the surrounding code.Usa esto como ayuda rápida de lectura, no como sustituto de trazar el código que rodea cada instrucción.
| ModeModo | SyntaxSintaxis | Typical reverse-engineering meaningLectura típica en ingeniería inversa |
|---|---|---|
| Data RegisterRegistro de datos | Dn | Temporary value / arithmeticValor temporal / aritmética |
| Address RegisterRegistro de dirección | An | PointerPuntero |
| IndirectIndirecto | (An) | Data pointed to by registerDatos apuntados por el registro |
| PostincrementPostincremento | (An)+ | Sequential stream/tableFlujo o tabla secuencial |
| PredecrementPredecremento | -(An) | Stack / reverse traversalPila / recorrido inverso |
| DisplacementDesplazamiento | d16(An) | Structure fieldCampo de estructura |
| IndexedIndexado | d8(An,Xn) | Array / lookup tableArray / tabla de búsqueda |
| AbsoluteAbsoluto | xxx.W/.L | Global data / hardwareDato global / hardware |
| PC-relativeRelativo a PC | d16(PC) | Nearby static dataDato estático cercano |
| ImmediateInmediato | #value | Constant / mask / IDConstante / máscara / ID |
Related Knowledge
These articles are already available and form the natural reading path around addressing modes. Additional links will be added when the reverse-engineering, pointer-table, VDP, and ROM-header articles have reviewed content.Estos artículos ya están disponibles y forman la ruta natural de lectura alrededor de los modos de direccionamiento. Se añadirán más enlaces cuando los artículos de ingeniería inversa, tablas de punteros, VDP y cabecera ROM tengan contenido revisado.