Comment ajouter un octet immédiat à un long registre avec la syntaxe AT&T sur x86?
-
29-10-2019 - |
Question
D'après ce que je comprends en lisant les manuels Intel, il devrait être possible d'écrire une instruction comme add $0x7f, %ebx
et il doit être codé comme 83 /0 ib
pour un total de trois octets.
Cependant, quand je fais ça (que j'utilise add
, addb
, ou addl
) il "favorise" la valeur immédiate à une valeur 32 bits et code comme 81 /0 id
et prend six octets. Le même problème existe avec adc
, sub
, etc. Notez que j'utilise la syntaxe AT&T avec GNU as
.
Je cherche une solution depuis plus d'une journée et je ne l'ai pas trouvée. Quelqu'un peut-il vous conseiller?
La solution
Étonnamment, je n'ai pas un tel problème.
J'ai pris ce code d'assembly produit par 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"
Et l'a compilé avec as
Et c'est ce que je vois dans 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
Et le programme C était:
volatile int x = 0;
int main(void)
{
x += 0x7F;
return 0;
}
Êtes-vous sûr que votre opérande immédiat peut être représentée comme un entier signé 8 bits? S'il est en dehors de la plage de -128 à +127, l'assembleur devra utiliser un codage plus long.