7.2 דפוסים באסמבלי תרגול
תרגול - דפוסים באסמבלי¶
תרגיל 1 - זיהוי מבנה C מאסמבלי¶
לכל קטע אסמבלי, זהו מהו מבנה ה-C שהוא מייצג (if, for, while, switch) ושחזרו את הקוד ב-C:
קטע א:
קטע ב:
קטע ג:
mov eax, edi
.L1:
test eax, eax
je .L2
mov edx, eax
shr edx, 1
add eax, edx
add eax, 1
jmp .L1
.L2:
ret
קטע ד:
cmp edi, 3
ja .default
lea rax, [rip + .jump_table]
movsxd rdx, dword [rax + rdi*4]
add rax, rdx
jmp rax
תרגיל 2 - חיזוי התנהגות¶
עבור כל קטע אסמבלי, עקבו ידנית אחרי הערכים באוגרים ונבאו מה ערך ההחזרה (rax/eax) עבור הקלט הנתון:
קטע א (קלט: edi = 5):
קטע ב (קלט: edi = 6):
קטע ג (קלט: edi = 10, esi = 3):
תרגיל 3 - התאמת קוד C לדיסאסמבלי¶
להלן 4 פונקציות C ו-4 קטעי אסמבלי. התאימו כל פונקציה לקטע הנכון:
פונקציות C:
// פונקציה A
int func_a(int *arr, int n) {
int max = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] > max)
max = arr[i];
}
return max;
}
// פונקציה B
int func_b(int x) {
int count = 0;
while (x != 0) {
count += x & 1;
x >>= 1;
}
return count;
}
// פונקציה C
void func_c(int *arr, int n) {
for (int i = 0; i < n; i++) {
arr[i] = arr[i] * 2;
}
return;
}
// פונקציה D
int func_d(int a, int b) {
if (a > b)
return a - b;
return b - a;
}
קטעי אסמבלי:
קטע 1:
קטע 2:
xor eax, eax
test edi, edi
je .end
.loop:
mov ecx, edi
and ecx, 1
add eax, ecx
shr edi, 1
test edi, edi
jne .loop
.end:
ret
קטע 3:
mov eax, [rdi]
mov ecx, 1
.loop:
cmp ecx, esi
jge .end
mov edx, [rdi + rcx*4]
cmp edx, eax
cmovg eax, edx
inc ecx
jmp .loop
.end:
ret
קטע 4:
תרגיל 4 - זיהוי אופטימיזציות¶
עבור כל קטע אסמבלי, הסבירו מהי האופטימיזציה שהקומפיילר עשה וכתבו את קוד ה-C המקורי:
קטע א:
קטע ב:
קטע ג:
קטע ד:
קטע ה:
תרגיל 5 - שחזור פונקציה מלאה¶
להלן דיסאסמבלי של פונקציה. שחזרו את קוד ה-C שלה, כולל שמות משמעותיים למשתנים:
mystery:
push rbp
mov rbp, rsp
push rbx
mov rbx, rdi ; שמירת ארגומנט ראשון (rdi)
xor eax, eax ; eax = 0
test rbx, rbx ; בדיקה אם rbx == NULL
je .end
xor eax, eax ; eax = 0
.loop:
cmp byte [rbx + rax], 0 ; בדיקה אם הבית במיקום rax הוא 0
je .end
inc rax ; rax++
jmp .loop
.end:
pop rbx
pop rbp
ret
רמזים:
- הפונקציה מקבלת ארגומנט אחד ב-rdi (כנראה מצביע)
- היא מחזירה ערך ב-rax
- חפשו דפוס של while loop
- מה עושה cmp byte [rbx + rax], 0?