سؤال

أنا أحاول أن أفهم بعض الجمعية.

الجمعية على النحو التالي, أنا مهتم في testl خط:

000319df  8b4508        movl   0x08(%ebp), %eax  
000319e2  8b4004        movl   0x04(%eax), %eax  
000319e5  85c0          testl  %eax, %eax  
000319e7  7407          je     0x000319f0  

أنا أحاول أن أفهم هذه النقطة من testl بين %eax و %eax?أعتقد تفاصيل ما هذا الرمز ليس مهما, أنا فقط أحاول أن أفهم الاختبار مع نفسه لا قيمة دائما يكون صحيحا ؟

هل كانت مفيدة؟

المحلول

وهي تختبر ما إذا كان eax 0 ، أو أعلاه أو أدناه.في هذه الحالة, القفز إذا eax 0.

نصائح أخرى

معنى test هو والحجج معا ، والتحقق من النتيجة صفر.حتى هذا الرمز الاختبارات إذا EAX هو صفر أو لا. je سوف تقفز إذا صفر.

راجع للشغل, وهذا يولد أصغر التعليمات من cmp eax, 0 والذي هو السبب في أن المجمعين عموما سوف تفعل ذلك بهذه الطريقة.

اختبار التعليمات لا منطقي بين المعاملات ولكن لا يكتب النتيجة مرة أخرى إلى السجل.فقط أعلام يتم تحديثها.

في المثال الخاص بك test eax, eax سيتم تعيين صفر العلم إذا eax هو صفر ، وعلامة العلم إذا كان أعلى قليلا تعيين بعض الأعلام الأخرى كذلك.

القفز إذا قدم المساواة (je) تعليمات يقفز إذا كان صفر العلم هو مجموعة.

يمكنك ترجمة التعليمات البرمجية أكثر قابلية للقراءة رمز مثل هذا:

cmp eax, 0
je  somewhere

له نفس الوظائف ولكن يتطلب بعض بايت المزيد من قانون الفضاء.وهذا هو السبب لماذا مترجم المنبعثة اختبار بدلا من مقارنة.

test مثل and, إلا أنه فقط يكتب الأعلام ، وترك كل المدخلات غير معدلة.مع اثنين من مختلفة المدخلات انها مفيدة لاختبار إذا كان بعض القطع كلها من الصفر ، أو إذا كان واحد على الأقل يتم تعيين.(مثلا ، test al, 3 مجموعات ZF إذا EAX هو من مضاعفات 4 (وبالتالي لديه كل انخفاض 2 بت صفرية).


test eax,eax مجموعات كل الأعلام بالضبط بنفس الطريقة التي cmp eax, 0 أن:

  • را من مسح (و/اختبار دائما يفعل ذلك ؛ وطرح صفر لم تنتج حمل)
  • ZF ، SF و PF وفقا قيمة EAX.(a = a&a = a-0)

(باستثناء عفا عليها الزمن AF (مساعد حمل العلم ، وتستخدم من قبل ASCII/BCD التعليمات). اختبار يترك غير معروف, ولكن CMP مجموعات أنه "وفقا النتيجة".منذ طرح الصفر لا يمكن أن تنتج حمل من 4 إلى 5 بت ، CMP ينبغي دائما واضحة AF).


اختبار أصغر (فوري) و في بعض الأحيان أسرع (أن الكلية الصمامات في مقارنة-و-فرع uop على المزيد من وحدات المعالجة المركزية في قضايا أكثر من اجتماع الأطراف). أن يجعل test يفضل لغة لاختبار سجل صفر أو لا.

المشترك الوحيد السبب في استخدام الأطراف العامل بوصفه اجتماع الأطراف مع فوري 0 عندما تريد مقارنة ضد الذاكرة المعامل (على سبيل المثال ، cmpb $0, (%esi) للتحقق من أجل إنهاء صفر بايت في نهاية ضمني طول ج-النمط string).


AVX512F يضيف kortestw k1, k2 و AVX512DQ/BW (Skylake ولكن ليس KNL) إضافة ktestb/w/d/q k1, k2, التي تعمل على AVX512 قناع السجلات (k0..k7) ولكن لا يزال تعيين العادية الأعلام مثل test هل بنفس الطريقة التي عدد صحيح OR أو AND تعليمات القيام به.

kortestw k1,k1 هو الاصطلاحية طريقة فرع / cmovcc / setcc على AVX512 مقارنة النتيجة استبدال SSE/AVX2 (v)pmovmskb/ps/pd + test أو cmp.


استخدام jz مقابل je يمكن أن يكون مربكا.

jz و je حرفيا نفس التعليمات, أينفس شفرة التشغيل في رمز الجهاز. يفعلون نفس الشيء, ولكن قد يختلف المعنى الدلالي للبشر.Disassemblers (عادة asm الناتج من المجمعين) فقط من أي وقت مضى استخدام واحد ، لذلك الدلالي التمييز المفقودة.

cmp و sub مجموعة ZF عندما اثنين من المدخلات تساوي (أيالطرح النتيجة 0). je (القفز إذا قدم المساواة) هو لغويا ذات الصلة مرادف.

test %eax,%eax / and %eax,%eax مرة أخرى مجموعات ZF عندما تكون النتيجة صفر, ولكن لا يوجد "المساواة" اختبار.ZF بعد اختبار لا أقول لكم ما إذا كان اثنين من المعاملات متساوية.لذلك jz (القفز إذا صفر) هو لغويا ذات الصلة مرادف.

هذا مقتطف من التعليمات البرمجية هو من روتين التي أعطيت مؤشر إلى شيء ، وربما بعض البنية أو كائن.2 خط dereferences هذا المؤشر ، وجلب قيمة من هذا الشيء - ربما في حد ذاته مؤشر أو ربما فقط int, تخزين 2 عضو (الأوفست +4).3 و 4 خطوط اختبار هذه القيمة صفر (NULL إذا كان المؤشر) و تخطي ما يلي بعض العمليات (لا يظهر) إذا كان هو صفر.

اختبار الصفر في بعض الأحيان يتم ترميز مثل مقارنة فورية الحرفي قيمة صفر, ولكن المترجم (أو الإنسان؟) الذي كتب هذا قد يعتقد testl المرجع تشغيل أسرع مع الأخذ بعين الاعتبار جميع الحديثة وحدة المعالجة المركزية الاشياء مثل pipelining و تسجيل تسمية.إنه من نفس كيس من الحيل التي يحمل فكرة المقاصة سجل مع XOR EAX,EAX (التي رأيت على شخص لوحة ترخيص في كولورادو!) وليس واضحا ولكن ربما أبطأ MOV EAX, #0 (يمكنني استخدام قديمة التدوين).

في asm مثل perl, TMTOWTDI.

إذا eax صفر فإنه سوف تؤدي المشروط القفز, وإلا فإنه سوف يستمر التنفيذ في 319e9

في بعض البرامج التي يمكن استخدامها للتحقق من تجاوز سعة المخزن المؤقت.في أعلى جدا من المساحة المخصصة 0 وضعت.بعد إدخال البيانات في كومة ، يبدو 0 في بداية جدا من المساحة المخصصة للتأكد من المساحة المخصصة لا فاضت.

انه كان يستخدم في stack0 ممارسة مآثر-تمارين للتحقق مما إذا كان فاض و إذا لم يكن هناك وكان هناك الصفر هناك ، فإنه عرض "حاول مرة أخرى"

0x080483f4 <main+0>:    push   ebp
0x080483f5 <main+1>:    mov    ebp,esp
0x080483f7 <main+3>:    and    esp,0xfffffff0
0x080483fa <main+6>:    sub    esp,0x60                     
0x080483fd <main+9>:    mov    DWORD PTR [esp+0x5c],0x0 ;puts a zero on stack
0x08048405 <main+17>:   lea    eax,[esp+0x1c]
0x08048409 <main+21>:   mov    DWORD PTR [esp],eax
0x0804840c <main+24>:   call   0x804830c <gets@plt>
0x08048411 <main+29>:   mov    eax,DWORD PTR [esp+0x5c] 
0x08048415 <main+33>:   test   eax,eax                  ; checks if its zero
0x08048417 <main+35>:   je     0x8048427 <main+51>
0x08048419 <main+37>:   mov    DWORD PTR [esp],0x8048500 
0x08048420 <main+44>:   call   0x804832c <puts@plt>
0x08048425 <main+49>:   jmp    0x8048433 <main+63>
0x08048427 <main+51>:   mov    DWORD PTR [esp],0x8048529
0x0804842e <main+58>:   call   0x804832c <puts@plt>
0x08048433 <main+63>:   leave
0x08048434 <main+64>:   ret

يمكننا أن نرى jgjle إذا testl %edx,%edx. jle .L3يمكننا من السهل العثور على jleهي دعوى (SF^OF)|ZFإذا %edx هو الصفر ZF=1,ولكن إذا edx غير الصفر و هي -1 ، بعد testl ، من=0 و SF =1 ، لذلك العلم =صحيح أن تنفيذ القفز .آسف لغتي الإنجليزية الفقراء

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