الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

Switch Case to Jump Address Table

بدأه Ah.K.EL-Saman في 20 مايو 2010 · 3 رد · 850 مشاهدة · في أرشيف قسم الـــ Assembly
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته,

اخوانى الكرام اما بعد السلام والتحية ,

قرأت فى كتاب Computer Organisation & Design 3rd Edition عن استخدام اسلوب الـ Jump Address Table فى عملية الترجمة لـ Switch Case Code من لغة High Level مثل لغة الـ C ولكنى لم أفهم كثيرا من الشرح حيث انه اعطى نبذة صغيرة فأتمنى من لديه المعرفة بهذا الجزء أن يعطينى مثال على Code يتم فيه تحويل Switch Case from High Level Language to Assembly Using Jump Address Table.

ولكم جزيل الشكر

سَبِّحِ اسْمَ رَبِّكَ الْأَعْلَى

#2

السلام عليكم ورحمة الله وبركاته,

شكراً جزيلا أخوانى وأخواتى لقد توصلت للحل أثناء بحثى صباحا ..

Consider this switch statement:. 
switch (k) {
case 0:
   k = i + j;
   break;
case 1:
   k = i - j;
   break;
case 4:
   k = i * j;
   break;
default:
   k = j / 2;
   break;
}

It could be implemented by a chain of comparisons, analagous to this C: 
if (k == 0)
   k = i + j;
else if (k == 1)
   k = i - j;
else if (k == 4)
   k = i * j;
else
   k = j / 2;

Can also be implemented by a jump table analagous to this pseudo-C 
address table[] = {label0,label1,label3,label3,label2};
if (k < 0 || k > 4)
	goto label3:
goto table[k];
label0:
   k = i + j;
   goto end;
label1:
   k = i - j;
   goto end;
label2:
   k = i * j;
   goto end;
label3:
   k = j / 2;
end:

You cannot do this in C - it has no datatype to store addresses. You can do it in assembler 

switch:
# assume k in $2
     blt  $2 $0 label3 # if (k < 0)
     li   $8 4         #    goto def;
     bgt  $2 $8 label3 # if (k > 4)
     li   $8 4         #    goto def;
     mul  $8 $2 $8     # offset = k*4;
     lw   $8 table($8)
     jr   $8           # goto table[k];
label0:
     add  $18 $16 $17  # k = i + j;
     j    end          # break;
label1:
    sub  $18 $16 $17   # k = i - j;
     j    end          # break;
label2:
     mul  $18 $16 $17  # k = i * j;
     j    end          # break;
label3:
     div  $18 $17 2    # k = j / 2;
end:...
     .data
table:
     .word label0, label1, label3, label3, label2

If there are many choices a jump table is more efficient.
1

سَبِّحِ اسْمَ رَبِّكَ الْأَعْلَى

#3

السلام عليكم،

توضيحاً لتعليمات الأسمبلر التي وردت في المثال الأخير في المشاركة أعلاه

blt = branch if less than

li = load immediate

bgt = branch if greater than

lw = load word

jr = conditional jump

j = unconditional jump

وفيما يلي مثال بالـ x86 instruction set:

include 'win32ax.inc'

.data
table dd 	case1,case2,case3,default

.code
start:
 	mov 	ecx,2 	; ECX = k
 	lea 	eax,[table]
 	mov 	ebx,[eax+ecx*4] ; [Base+Index*Scale] - check: http://www.cs.umbc.edu/courses/undergraduate/CMPE310/Spring04/cpatel2/slides/lab_slides/assem1_extra.pdf
 	jmp 	ebx
 case1:
 	xor 	edx,edx
 	jmp 	fin
 case2:
 	xor 	edx,edx
 	jmp 	fin
 case3:
 	xor 	edx,edx
 	jmp 	fin
 default:
 	xor 	ebx,ebx
 fin:

 	invoke ExitProcess,0

.end start

* الكود يخلص Fasm32

تم تعديل هذه المشاركة بواسطة Xacker في 23 مايو 2010 في 15:24

1

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#4

جزاك الله كل خير حقيقى إضافة رائعة أفدتنى كتير وده مش جديد عليك

سَبِّحِ اسْمَ رَبِّكَ الْأَعْلَى

مواضيع مشابهة