كيفية إضافة بايت فوري إلى سجل طويل باستخدام بناء جملة AT&T على x86؟
-
29-10-2019 - |
سؤال
من ما أفهمه من خلال قراءة أدلة إنتل، يجب أن يكون من الممكن كتابة تعليمات مثل add $0x7f, %ebx
ويجب ترميزه كـ 83 /0 ib
ليصبح المجموع ثلاثة بايت.
ومع ذلك، عندما أفعل هذا (سواء كنت أستخدم add
, addb
, ، أو addl
) يقوم دائمًا "بترقية" القيمة الفورية إلى قيمة 32 بت وترميزها كـ 81 /0 id
ويستغرق ستة بايت.نفس المشكلة موجودة مع adc
, sub
, ، إلخ.لاحظ أنني أستخدم بناء جملة AT&T مع GNU as
.
لقد كنت أبحث عن حل منذ أكثر من يوم ولم أجده.يمكن لأي شخص يرجى تقديم المشورة؟
المحلول
والمثير للدهشة أنه ليس لدي مثل هذه المشكلة.
أخذت رمز التجميع هذا الذي أنتجته gcc
(دججب):
.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"
وجمعت معه 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
وكان برنامج C:
volatile int x = 0;
int main(void)
{
x += 0x7F;
return 0;
}
هل أنت متأكد من أنه يمكن تمثيل المعامل المباشر الخاص بك كعدد صحيح موقّع 8 بت؟إذا كان خارج نطاق -128 إلى +127، فسيتعين على المجمّع استخدام ترميز أطول.