ההההההה ההההה- ההההה הAssembly ( הההה ההההmerge sort )
Dec 21, 2015
מוסכמות קריאה Assemblyלשגרה ב-
(merge sortמיון מערך )
merge-sort
אם המקרה טריוויאלי )איבר אחד או שניאיברים( מיין והחזר
אחרת חלק את המערך לשני חלקים ומיין כלאחד מהם לחוד )קריאה רקורסיבית(
מזג את שני החלקים הממוינים
8 12 176 7 91- 52 164 3215 2 16 4 32 1 8 12 17 6 7 9 1-8 12 176 7 91-52 164 321
52 164 3215 2 16 4 32 14 321
414 32 1321
52 16
5 252
דוגמא למיון מערך
16
5 2 16 4 32 1321
תהליך...דומה
32171612987654211-
8 12 176 7 91-52 164 321
פעולת מיזוג
ממשו בשפת אסמבלי את התכנית הבאה בצורה רקורסיבית:merge-sortהמבצעת
#define MAX_NUM 20
void main)void({
int ar[ ] = {5, 2, 16, 4, 32, 1, 8, 12, 17, 6, 7, 9, -1};
int n = 13;
int br[MAX_NUM];
sort)ar, n, br(;
}
// Sort array A[ ] of size n to array B[ ]void sort)int A[ ], int n, int B[ ]({
int A1[MAX_NUM], A2[MAX_NUM];int n1, n2;
if )n == 1( {B[0] = A[0];return;
} else if )n == 2( {merge)A, A+1, B, 1, 1(;return;
} else { n1 = n/2;n2 = n - n1;sort)A, n1, A1(;sort)A+n1, n2, A2(;merge)A1, A2, B, n1, n2(;return;
}}
// Merge two sorted arrays P[ ] and Q[ ] of size p and q, respectively, to array R[ ]void merge)int P[ ], int Q[ ], int R[ ], int p, int q({
int i, j, k;
i = j = k = 0;while )i < p && j < q( {
if )P[i] < Q[j](R[k++] = P[i++];
else R[k++] = Q[j++];
}while )i < p(
R[k++] = P[i++]; while )j < q(
R[k++] = Q[j++];}
הירארכיה בין השגרות
main sort
merge
sort
Caller
Callee
תחום הכתובות אליהן ניגשים ביחס
fp$ל-
עבור כל שיגרה מוקצה איזור זיכרון לטובת:frameבמחסנית הנקרא
- העברת ארגומנטים מעבר לארבעה
- שמירת תוכן הרגיסטרים אשר השיגרה הקוראת לא מעוניינת
בשינוי שלהם - עבור משתנים פנימיים של
השיגרה
Argument 6
Argument 5
Callee saved registers
Local variables
$fp
$sp
Argument N
Argument M
Argument 5
Current
frame
Previousfram
eN
extfram
e
Inco
min
gar
gum
ents
Out
goin
gar
gum
ents
Lower addresses
מבנה המחסנית )תזכורת(
חישוב גודל המסגרות של השגרות
Main Sort Merge
Callee saved registers
$a0
$a1
$a2
$ra
$fp
$a0
$a1
$a2
$a3
$ra
$fp
$s0
$s1
$s2
$s3
$fp
Local variables A1[MAX_NUM]
A2[MAX_NUM]
Frame size 5*4=20 6*4+2*20*4=184 5*4=20
sortמבנה המסגרת של השגרה
$a0
$a1
$a2
$a3
$ra
$fp )old(
A1[19]
A1[18]
A1[0]
A2[19]
A2[18]
A2[0]
$fp
$fp - 4
$fp - 8
$fp -100
$fp -180
$fp + 4
תרגסמהלשsort
merge לפני הקריאה ל- sortמבנה המסגרת של
Argument 5
$a0
$a1
$a2
$a3
$ra
$fp )old(
A1[19]
A1[18]
A1[0]
A2[19]
A2[18]
A2[0]
$fp
$fp - 4
$fp - 8
$fp -100
$fp -180
$fp + 4
תרגסמהלשsort
mainמימוש השגרה main:
addiu $sp, $sp, -20 # stack frame size is 20 bytessw $ra, 4)$sp( # save return addresssw $fp, 0)$sp( # save frame pointeraddiu $fp, $sp, 16 # set frame pointersw $a0, 0)$fp( # save $a0sw $a1, -4)$fp( # save $a1sw $a2, -8)$fp( # save $a2
la $a0, ar # initialize the first argumentlw $a1, n # initialize the second argumentla $a2, br # initialize the third argumentjal sort # call factorial function
lw $a0, 0)$fp( # restore $a0lw $a1, -4)$fp( # restore $a1lw $a2, -8)$fp( # restore $a2lw $ra, 4)$sp( # restore return addresslw $fp, 0)$sp( # restore frame pointeraddiu $sp, $sp, 20 # pop the stackjr $ra # return to caller
Sort )prologue(sort:
addiu $sp, $sp, -184 # stack frame size is 184 bytessw $ra, 164)$sp( # save return addresssw $fp, 160)$sp( # save frame pointeraddiu $fp, $sp, 180 # set frame pointersw $a0, 0)$fp( # save the first argumentsw $a1, -4)$fp( # save the second argumentsw $a2, -8)$fp( # save the third argumentsw $a3, -12)$fp( # save the fourth argument
Sort )trivial case(li $t0, 2 # if )n > 2(bgt $a1, $t0, callagain # it’s not a trivial case, go to recursive callbeq $a1, $t0, simplemergelw $t1, 0)$a0( #sw $t1, 0)$a2( # B[0] = A[0];j finishsort
simplemerge:addi $a1, $a0, 4ori $a3, $zero, 1ori $t1, $zero, 1addiu $sp, $sp, -4 # push the fifth argument to the stacksw $t1, 0)$sp(jal merge # call merge)A, A+1, B, 1, 1(addiu $sp, $sp, 4 # pop the fifth argumentj finishsort
Sort )recursive call(callagain:
srl $t1, $a1, 1move $a1, $t1addiu $a2, $fp, -100jal sort
add $t0, $a1, $a1add $t0, $t0, $t0add $a0, $a0, $t0lw $t1, -4)$fp(sub $a1, $t1, $a1addiu $a2, $fp, -180jal sort
addiu $a0, $fp, -100addiu $sp, $sp, -4 # push the fifth argument to the stacksw $a1, 0)$sp(lw $t1, -4)$fp(sub $a3, $t1, $a1addiu $a1, $fp, -180lw $a2, -8)$fp(jal mergeaddiu $sp, $sp, 4 # pop the fifth argument
Sort )epilogue(finishsort:
lw $a0, 0)$fp( # save the first argumentlw $a1, -4)$fp( # save the second argumentlw $a2, -8)$fp( # save the third argumentlw $a3, -12)$fp( # save the fourth argumentlw $ra, 164)$sp( # restore return addresslw $fp, 160)$sp( # restore frame pointeraddiu $sp, $sp, 184 # pop the stackjr $ra # return to caller
merge )prologue+(merge:
addiu $sp, $sp, -20 # stack frame size is 20 bytes
sw $fp, 0)$sp( # save frame pointer
addiu $fp, $sp, 16 # set frame pointer
sw $s0, 0)$fp(
sw $s1, -4)$fp(
sw $s2, -8)$fp(
sw $s3, -12)$fp(
li $s0, 0 # i = 0
li $s1, 0 # j = 0
li $s2, -1 # k = -1
lw $s3, 4)$fp( # $t0 = n2