[英]How to add an immediate byte to a long register with AT&T syntax on x86?
From what I understand reading the Intel manuals, it should be possible to write an instruction like add $0x7f, %ebx
and it should be encoded as 83 /0 ib
for a total of three bytes. 根据我的理解阅读英特尔手册,应该可以写一个像add $0x7f, %ebx
这样的指令,它应该被编码为83 /0 ib
,总共三个字节。
However, when I do this (whether I use add
, addb
, or addl
) it always "promotes" the immediate value to a 32-bit value and encodes as 81 /0 id
and takes up six bytes. 但是,当我这样做时(无论我使用add
, addb
还是addl
),它总是将“立即值”提升为32位值并编码为addl
81 /0 id
并占用6个字节。 The same problem exists with adc
, sub
, etc. Note that I am using AT&T syntax with GNU as
. adc
, sub
等存在同样的问题。请注意,我使用AT&T语法和GNU as
。
I have been looking for a solution for over a day and haven't found it. 我一直在寻找解决方案超过一天,但没有找到它。 Can anyone please advise? 任何人都可以建议吗?
Surprisingly, I don't have such a problem. 令人惊讶的是,我没有这样的问题。
I took this assembly code produced by gcc
(DJGPP): 我拿了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"
And compiled it with as
and this is what I'm seeing in a.out: 用as
编译它,这就是我在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
And the C program was: C程序是:
volatile int x = 0;
int main(void)
{
x += 0x7F;
return 0;
}
Are you sure your immediate operand can be represented as an 8-bit signed integer? 您确定您的立即操作数可以表示为8位有符号整数吗? If it's outside the -128 to +127 range, the assembler will have to use a longer encoding. 如果它超出-128到+127范围,汇编器将不得不使用更长的编码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.