Mientras que la construcción de mi ensamblador para la plataforma x86 me encontré con algunos problemas con que codifica la JMP
instrucción:¿Cómo se implementa un JMP (x86) relativo en un ensamblador?
OPCODE INSTRUCTION SIZE
EB cb JMP rel8 2
E9 cw JMP rel16 4 (because of 0x66 16-bit prefix)
E9 cd JMP rel32 5
...
(de mi sitio web favorito de instrucciones x86, http://siyobik.info/index.php?module=x86&id=147)
Todos son relativos saltos, donde el tamaño de cada codificación (operación + operando) está en la tercera columna.
Ahora mi original (y por tanto de fallos debido a esto) el diseño se reservó el espacio máximo (5 bytes) para cada instrucción. El operando aún no se conoce porque es un salto a una ubicación aún desconocida. Así que implementé un mecanismo de "reescritura", que reescribe los operandos en la ubicación correcta de la memoria, si se conoce la ubicación del salto, y rellena el resto con NOP
s. Esta es una preocupación un tanto seria en tight-loops.
Ahora mi problema es con la siguiente situación:
b: XXX
c: JMP a
e: XXX
...
XXX
d: JMP b
a: XXX (where XXX is any instruction, depending
on the to-be assembled program)
El problema es que quiero la codificación más pequeña posible para una instrucción JMP
(y sin NOP
llenado).
Tengo que saber el tamaño de la instrucción en c
antes de que pueda calcular la distancia relativa entre a
y b
para el operando en d
. Lo mismo se aplica para el JMP
en c
: lo que necesita saber el tamaño de d
antes de que pueda calcular la distancia relativa entre e
y a
.
¿Cómo montadores existentes resuelven este problema, o ¿cómo hacer esto?
Esto es lo que estoy pensando que resuelve el problema:
Primera codificar todas las instrucciones a los códigos de operación entre el
JMP
y su objetivo, en esta región contiene un código de operación de tamaño variable, utilice el tamaño máximo , p.ej5
para unJMP
. Luego codifique el relativoJMP
en su objetivo, eligiendo el tamaño de codificación más pequeño posible (3, 4 o 5) y calcule la distancia. Si se codifica cualquier código de operación de tamaño variable, cambie todos los operandos absolutos antes, y todas las instrucciones relativas que omitan esta instrucción codificada: se vuelven a codificar cuando su operando cambia para elegir el tamaño más pequeño posible. Se garantiza que este método finalizará, ya que los códigos de operación de tamaño variable solo pueden reducirse (porque usan el tamaño máximo de los mismos).
Me pregunto, tal vez esta es una solución más de la ingeniería, por eso hago esta pregunta.
+1 para el enlace bonita documentación asm –