¿Cómo agregar un byte inmediato a un registro largo con la sintaxis de AT&T en x86?
-
29-10-2019 - |
Pregunta
Por lo que entiendo al leer los manuales de Intel, debería ser posible escribir una instrucción como add $0x7f, %ebx
y debería estar codificada como 83 /0 ib
para un total de tres bytes.
Sin embargo, cuando hago esto (ya sea que use add
, addb
o addl
) siempre "promueve" el valor inmediato a un valor de 32 bits y codifica como 81 /0 id
y ocupa seis bytes.Existe el mismo problema con adc
, sub
, etc. Tenga en cuenta que estoy usando la sintaxis de AT&T con GNU as
.
He estado buscando una solución durante más de un día y no la he encontrado.¿Alguien puede aconsejarme?
Solución
Sorprendentemente, no tengo tal problema.
Tomé este código de montaje producido por gcc
(DJGPP):
.file "im.c"
.globl _x
.section .bss
.p2align 2
_x:
.space 4
.section .text
.p2align 4,,15
.globl _main
_main:
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %eax
movl _x, %eax
andl $-16, %esp
addl $127, %eax
movl %eax, _x
movl %ebp, %esp
xorl %eax, %eax
popl %ebp
ret
.ident "GCC: (GNU) 3.3.4"
y lo compiló con as
y esto es lo que estoy viendo en a.out:
55 push ebp
89E5 mov ebp,esp
50 push eax
50 push eax
A100000000 mov eax,[0x0]
83E4F0 and esp,byte -0x10
83C07F add eax,byte +0x7f
A300000000 mov [0x0],eax
89EC mov esp,ebp
31C0 xor eax,eax
5D pop ebp
C3 ret
y el programa C fue:
volatile int x = 0;
int main(void)
{
x += 0x7F;
return 0;
}
¿Está seguro de que su operando inmediato se puede representar como un entero firmado de 8 bits?Si está fuera de la gama -128 a +127, el ensamblador tendrá que usar una codificación más larga.