Come aggiungere un byte immediato a un registro lungo con la sintassi AT&T su x86?
-
29-10-2019 - |
Domanda
Da quello che ho capito leggendo i manuali Intel, dovrebbe essere possibile scrivere un'istruzione come add $0x7f, %ebx
e dovrebbe essere codificata come 83 /0 ib
per un totale di tre byte.
Tuttavia, quando lo faccio (sia che io usi add
, addb
o addl
) "promuove" sempre il valore immediato a un valore a 32 bit e codifica come 81 /0 id
e occupa sei byte.Lo stesso problema esiste con adc
, sub
, ecc. Nota che sto usando la sintassi AT&T con GNU as
.
Ho cercato una soluzione per più di un giorno e non l'ho trovata.Qualcuno può consigliare?
Soluzione
Sorprendentemente, non ho questo problema.
Ho preso questo codice assembly prodotto da 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"
E l'ho compilato con as
e questo è quello che vedo in 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
E il programma C era:
volatile int x = 0;
int main(void)
{
x += 0x7F;
return 0;
}
Sei sicuro che il tuo operando immediato possa essere rappresentato come un intero con segno a 8 bit?Se è al di fuori dell'intervallo compreso tra -128 e +127, l'assemblatore dovrà utilizzare una codifica più lunga.