`testl` eax ضد eax?
-
02-07-2019 - |
سؤال
أنا أحاول أن أفهم بعض الجمعية.
الجمعية على النحو التالي, أنا مهتم في 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
يمكننا أن نرى jg,jle
إذا testl %edx,%edx. jle .L3
يمكننا من السهل العثور على jleهي دعوى (SF^OF)|ZF
إذا %edx هو الصفر ZF=1,ولكن إذا edx غير الصفر و هي -1 ، بعد testl ، من=0 و SF =1 ، لذلك العلم =صحيح أن تنفيذ القفز
.آسف لغتي الإنجليزية الفقراء