كيفية إضافة بايت فوري إلى سجل طويل باستخدام بناء جملة AT&T على x86؟

StackOverflow https://stackoverflow.com/questions/8409707

سؤال

من ما أفهمه من خلال قراءة أدلة إنتل، يجب أن يكون من الممكن كتابة تعليمات مثل 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، فسيتعين على المجمّع استخدام ترميز أطول.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top