31
ייייייי יייייייx86_64 יייMinGcc ררררר ררררר ררר ררר ררר ררררררררminGW64 . רררר רררררר רררר ררר:https://sourceforge.net/projects/mingw-w64 / רררר רררררר רר- יייי יx86_64 ררר רר ררררר רררררi686 . רררר רררררר, ררר ררר רררררר ררררר רררר רררררrun terminal רררר רררררר רר ררררר ררררcmd רררררר רר רררררmingw-w64.bat רררר ררררcmd . - ררר רררר ררררר ררר רר רררררר רררררר רC , ררררר רר רררר ררררררר ר"ר ררררר ררררר רר ררררררC ררררר רר רררררר ררר ררררר רר)ררר ררר( ררררררר רררר.- רר ר ררררררר ררררר רררר רר רררררררgcc ררר רררר רררר ררררר ררררררר רררררר רררררר, ררר רר ררררר, רררר ררררר ררררררר ררררר ררררררgcc –S –masm=intel myprog.c ררררר ררררmyprog.s רררררר רררר ררר רררררר. רררר רררררר ררררר)ררררר ררררר( רררר ררר ררררר ררררררררררר( main.c רררררר ררררר)

math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

Embed Size (px)

Citation preview

Page 1: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

MinGcc תחת x86_64 תוכניות באסמבלי

. minGW64לצורך הקורס הזה הכי נוח בקומפילר

/https://sourceforge.net/projects/mingw-w64 ניתן להוריד אותו כאן:

.i686 ולא את ברירת המחדל x86_64גרסת ה-חשוב להתקין את

run terminalאחרי ההתקנה, בכל פעם שרוצים לעבוד צריך לעשות mingw-w64.bat ולהריץ את הקובץ cmdחלון מתוך התוכנה או לפתוח

.cmdמתוך חלון

, לתרגם את הקודCהכי מעשי לכתוב קוד של הפעולה הרצויה ב- לאסמבלי )ראה מיד( לקרואCלאסמבלי ע"י פקודת תרגום של תוכנית

את הפתרון משם וליעל את הקוד.

קצת שונה מזה שלgccהסינטקס ברירת מחדל של האסמבלי של ה- אינטל, בכדי לעבוד בסינטקס שאנחנו מכירים, בכדי להמיר לאסמבלי

נשתמש בפקודה

gcc –S –masm=intel myprog.c

ולשנות אותו לפי הצרכים.myprog.sולקבל קובץ

לאחר מכן לכתוב )במידת הצורך( קובץ תוכנית ראשית באסמבלי

( ולבסוף לקמפלmain.c)נניח

gcc main.c myprog.s

".a.exeקובץ ההרצה יהיה "

התייחסות לאוגרים:

Page 2: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

4 הבתים הראשונים, 2לכל האוגרים ניתן להתיחס לבית התחתון, :r8הבתים הראשונים וכולו, למשל עבור

r8b, r8w, r8d, r8

,raxלשמונת האוגרים הראשונים אפשר להתיחס בשמות הישנים למשל eax, ax,ah,al-וכו', אבל ל rax אפשר גם לקרוא r0, r0d, r0l,r0b.'וכו

משתנים שלמים:

קומפילר הזה גודל המשתנים השלמים הם:ב

char 1 בית

short int 2 בתים

int 4 בתים

long int 4 בתים

long long int 8 בתים -

ניתן לראות זאת בתוכנית הזו:

// ints.c#include <stdio.h>

char c1=1,c2 = 1;short int si1=2, si2=2;int i1=3, i2=3;long int li1 = 4, li2= 4;long long int lli1=5, lli2 =5;

Page 3: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

int main(){

printf("sizeof(char) = %d, sizeof(short int) = %d,\n" "sizeof(int) = %d, sizeof(long int) = %d,\n" "sizeof(long long int) = %d\n", sizeof(char), sizeof(short int), sizeof(int), sizeof(long int), sizeof(long long int));

c1 = c1 + c2;si1 = si1 + si2;i1 = i1 + i2;li1 = li1 + li2;lli1 = lli1 + lli2;

printf("c1 = %d, si1 = %d, i1 = %d, li1 = %ld, lli1 = %lld\n", c1, si1, i1, li1, lli1);

} //main

קומפילציה והרצה:

D:\asm64>gcc ints.c

D:\asm64>a.exesizeof(char) = 1, sizeof(short int) = 2,sizeof(int) = 4, sizeof(long int) = 4,sizeof(long long int) = 8c1 = 2, si1 = 4, i1 = 6, li1 = 8, lli1 = 10

D:\asm64>

עם התוכן הבא:ints.s נקבל קובץ gcc -S -masm=intel ints.cאחרי ביצוע

Page 4: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

.file "ints.c"

.intel_syntax noprefix

.globl c1

.datac1:

.byte 1

.globl c2c2:

.byte 1

.globl si1

.align 2si1:

.word 2

.globl si2

.align 2si2:

.word 2

.globl i1

.align 4i1:

.long 3

.globl i2

.align 4i2:

.long 3

.globl li1

.align 4li1:

.long 4

.globl li2

.align 4li2:

.long 4

.globl lli1

.align 8lli1:

.quad 5

.globl lli2

.align 8lli2:

Page 5: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

.quad 5

.def __main; .scl 2; .type 32; .endef

.section .rdata,"dr"

.align 8.LC0:

.ascii "sizeof(char) = %d, sizeof(short int) = %d,\12sizeof(int) = %d, sizeof(long int) = %d,\12sizeof(long long int) = %d\12\0"

.align 8.LC1:

.ascii "c1 = %d, si1 = %d, i1 = %d, li1 = %ld, lli1 = %lld\12\0"

.text

.globl main

.def main; .scl 2; .type 32; .endef

.seh_proc mainmain:

push rbp.seh_pushreg rbpmov rbp, rsp.seh_setframe rbp, 0sub rsp, 48.seh_stackalloc 48.seh_endprologuecall __mainmov QWORD PTR 40[rsp], 8mov QWORD PTR 32[rsp], 4mov r9d, 4mov r8d, 2mov edx, 1lea rcx, .LC0[rip]call printfmovzxeax, BYTE PTR c1[rip]mov edx, eaxmovzxeax, BYTE PTR c2[rip]add eax, edxmov BYTE PTR c1[rip], almovzxeax, WORD PTR si1[rip]mov edx, eaxmovzxeax, WORD PTR si2[rip]add eax, edxmov WORD PTR si1[rip], ax

Page 6: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

mov edx, DWORD PTR i1[rip]mov eax, DWORD PTR i2[rip]add eax, edxmov DWORD PTR i1[rip], eaxmov edx, DWORD PTR li1[rip]mov eax, DWORD PTR li2[rip]add eax, edxmov DWORD PTR li1[rip], eaxmov rdx, QWORD PTR lli1[rip]mov rax, QWORD PTR lli2[rip]add rax, rdxmov QWORD PTR lli1[rip], raxmov rcx, QWORD PTR lli1[rip]mov edx, DWORD PTR li1[rip]mov r9d, DWORD PTR i1[rip]movzxeax, WORD PTR si1[rip]movsxr8d, axmovzxeax, BYTE PTR c1[rip]movsxeax, almov QWORD PTR 40[rsp], rcxmov DWORD PTR 32[rsp], edxmov edx, eaxlea rcx, .LC1[rip]call printfmov eax, 0add rsp, 48pop rbpret.seh_endproc.ident "GCC: (x86_64-posix-seh-rev1, Built by MinGW-W64 project) 6.3.0".def printf; .scl 2; .type 32; .endef

העברת פרמטרים

Page 7: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

4למעט בקומפילר הזה הפרמטרים נדחפים למחסנית מימין לשמאל, שמוקצה להם מקום, אבל ערכיהם מועבריםהסקלרים הראשונים

או בחלקים שלהם, בהתאםrcx, rdx, r8, r9באוגרים )משמאל לימין( לגודל הפרמטר. לדוגמא, בקריאה

u = f(x, y, z);

, אםr8b הוא יועבר ב-char, הפרמטר השלישי משמאל הוא הוא zאם , ואם הואr8d יועבר ב-int, long, אם הוא r8w הוא יועבר ב-short intהוא

long long int-יועבר ב r8.

.cl, cx, ecx, rcx, הפרמטר הראשון יהיו xההעברות המקבילות ל-

לדוגמא, המימוש באסמבלי של התוכנית הבאה:

long long int z;

long long int fun(long long int x1,long long int x2,long long int x3,long long int x4,long long int x5,long long int x6,long long int x7,long long int x8,long long int x9,long long int x10){x1 = x1 + 1;x2 = x2 + 2;x3 = x3 + 3;x4 = x4 + 4;x5 = x5 + 5;x6 = x6 + 6;x7 = x7 + 7;x8 = x8 + 8;x9 = x9 + 9;x10 = x10 + 10;z = x1+x2+x3+x4+x5+x6+x7+x8+x9+x10;return z;}

יהיה:.file "pars1.c".intel_syntax noprefix

Page 8: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

.comm z, 8, 3

.text

.globl fun

.def fun; .scl 2; .type 32; .endef

.seh_proc funfun:

push rbp.seh_pushreg rbpmov rbp, rsp.seh_setframe rbp, 0.seh_endprologuemov QWORD PTR 16[rbp], rcxmov QWORD PTR 24[rbp], rdxmov QWORD PTR 32[rbp], r8mov QWORD PTR 40[rbp], r9add QWORD PTR 16[rbp], 1add QWORD PTR 24[rbp], 2add QWORD PTR 32[rbp], 3add QWORD PTR 40[rbp], 4add QWORD PTR 48[rbp], 5add QWORD PTR 56[rbp], 6add QWORD PTR 64[rbp], 7add QWORD PTR 72[rbp], 8add QWORD PTR 80[rbp], 9add QWORD PTR 88[rbp], 10mov rdx, QWORD PTR 16[rbp]mov rax, QWORD PTR 24[rbp]add rdx, raxmov rax, QWORD PTR 32[rbp]add rdx, raxmov rax, QWORD PTR 40[rbp]add rdx, raxmov rax, QWORD PTR 48[rbp]

Page 9: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

add rdx, raxmov rax, QWORD PTR 56[rbp]add rdx, raxmov rax, QWORD PTR 64[rbp]add rdx, raxmov rax, QWORD PTR 72[rbp]add rdx, raxmov rax, QWORD PTR 80[rbp]add rdx, raxmov rax, QWORD PTR 88[rbp]add rdx, raxlea rax, z[rip]mov QWORD PTR [rax], rdxlea rax, z[rip]mov rax, QWORD PTR [rax]pop rbpret.seh_endproc.ident "GCC: (x86_64-posix-seh-rev1, Built by MinGW-W64

project) 6.3.0"

דוגמאות:

// call_id3.c - call assembler subroutine idiv_mod64.s from C program #include <stdio.h> extern int idiv_mod64(long long int Num, long long int Denom, long long int *Q, long long int *Rem); int main() { long long int Num, Denom, Q, Rem; int No_Zero_Divide; printf("\nEnter Numerator, Denominator\n:");

Page 10: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

scanf("%lld %lld",&Num, &Denom); No_Zero_Divide = idiv_mod64(Num,Denom,&Q,&Rem); if (No_Zero_Divide)

printf("\n %lld div %lld = %lld, mod(%lld,%lld) = %lld\n", Num, Denom, Q, Num, Denom, Rem);

else printf("\nError: Zero Divide.\n"); return 0; } /* main */

// idiv_mod64.cint idiv_mod64(long long int Num, long long int Denom, long long int *Q, long long int *Rem){ if(Denom == 0) return 0;*Q = Num/Denom;*Rem = Num % Denom;

return 1;

} // idiv_mod64קמפול ופלט ריצה:

D:\asm64>gcc call_id3.c idiv_mod64.c

D:\asm64>a.exe

Enter Numerator, Denominator:1000000000000 12345679

1000000000000 div 12345679 = 81000, mod(1000000000000,12345679) = 1000

D:\asm64> שנוצר ע"י idiv_mod64.sהקובץ

D:\asm64>gcc -S -masm=intel idiv_mod64.c

Page 11: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

יהיה:.file "idiv_mod64.c".intel_syntax noprefix.text.globl idiv_mod64.def idiv_mod64; .scl 2; .type 32; .endef.seh_proc idiv_mod64

idiv_mod64:push rbp.seh_pushreg rbpmov rbp, rsp.seh_setframe rbp, 0.seh_endprologuemov QWORD PTR 16[rbp], rcxmov QWORD PTR 24[rbp], rdxmov QWORD PTR 32[rbp], r8mov QWORD PTR 40[rbp], r9cmp QWORD PTR 24[rbp], 0jne .L2mov eax, 0jmp .L3

.L2:mov rax, QWORD PTR 16[rbp]cqoidiv QWORD PTR 24[rbp]mov rdx, raxmov rax, QWORD PTR 32[rbp]mov QWORD PTR [rax], rdxmov rax, QWORD PTR 16[rbp]cqoidiv QWORD PTR 24[rbp]mov rax, QWORD PTR 40[rbp]mov QWORD PTR [rax], rdxmov eax, 1

.L3:pop rbpret

Page 12: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

.seh_endproc

.ident "GCC: (x86_64-posix-seh-rev1, Built by MinGW-W64 project) 6.3.0"

ייעול ידני של התוכנית:.file "idiv_mod64.c".intel_syntax noprefix.text.globl idiv_mod64.def idiv_mod64; .scl 2; .type 32; .endef.seh_proc idiv_mod64

idiv_mod64:push rbp.seh_pushreg rbpmov rbp, rsp.seh_setframe rbp, 0.seh_endprologue

mov rbx,rdxcmp rbx, 0jne .L2mov eax, 0jmp .L3

.L2:mov rax,rcxcqoidiv rbxmov [r8], raxmov [r9], rdxmov eax, 1

.L3:pop rbpret.seh_endproc.ident "GCC: (x86_64-posix-seh-rev1, Built by MinGW-W64

project) 6.3.0".def print; .scl 2; .type 32; .endef

Page 13: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

לעומת מימוש ידני באסמבלי:C הבודקת יעילות יחסית של המימוש ב-Cתוכנית

// call_id4.c - call assembler subroutine idiv_mod64.s from C program #include <stdio.h>#include <stdlib.h> extern int idiv_mod64(long long int Num, long long int Denom, long long int *Q, long long int *Rem); int main() { long long int Num, Denom, Q, Rem; int No_Zero_Divide; int i; printf("\nEnter Numerator, Denominator\n:"); scanf("%lld %lld",&Num, &Denom); system("time"); for(i=0; i< 1000000000;i++) No_Zero_Divide = idiv_mod64(Num,Denom,&Q,&Rem); system("time"); if (No_Zero_Divide)

printf("\n %lld div %lld = %lld, mod(%lld,%lld) = %lld\n", Num, Denom, Q, Num, Denom, Rem);

else printf("\nError: Zero Divide.\n"); return 0; } /* main */

:Cאפשר לראות את ההבדלים בייעול הודות לתכנות באסמבלי לעומת

F:\asm64>gcc call_id4.c idiv_mod64.c

F:\asm64>a.exe

Page 14: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

Enter Numerator, Denominator:100000000000000 81The current time is: 1:46:47.23Enter the new time:The current time is: 1:47:07.96Enter the new time:

100000000000000 div 81 = 1234567901234, mod(100000000000000,81) = 46

F:\asm64>gcc call_id4.c idiv_mod64.s

F:\asm64>a.exe

Enter Numerator, Denominator:100000000000000 81The current time is: 1:47:55.35Enter the new time:The current time is: 1:48:05.91Enter the new time:

100000000000000 div 81 = 1234567901234, mod(100000000000000,81) = 46

F:\asm64>

.50% או 10/20שיפור של

קימפול התוכנית הבאה לאסמבלי ממחישה את שיטת מימוש:x86_64המשתנים ב-

unsigned long int g = 5555; // g - global variable

Page 15: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

int f(int x) // x - parameter{ int y1; long int y2; // y1, y2 local //automatic int y3=99; // y3 local //automatic initialized static long int z=77; // z local static y1 = x+ z; z= x; y2 = y3; y3 = z; g = z+y2;} // f

:gcc –S –masm=intel vars1.c שנוצר מתוך vars1.sקובץ אסמבלי

.file "vars1.c"

.intel_syntax noprefix

.globl g

.data

.align 4g:

.long 5555

.text

.globl f

.def f; .scl 2; .type 32; .endef

.seh_proc ff:

push rbp.seh_pushreg rbpmov rbp, rsp.seh_setframe rbp, 0sub rsp, 16.seh_stackalloc 16.seh_endprologuemov DWORD PTR 16[rbp], ecxmov DWORD PTR -4[rbp], 99mov edx, DWORD PTR z.1775[rip]mov eax, DWORD PTR 16[rbp]add eax, edx

Page 16: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

mov DWORD PTR -8[rbp], eaxmov eax, DWORD PTR 16[rbp]mov DWORD PTR z.1775[rip], eaxmov eax, DWORD PTR -4[rbp]mov DWORD PTR -12[rbp], eaxmov eax, DWORD PTR z.1775[rip]mov DWORD PTR -4[rbp], eaxmov edx, DWORD PTR z.1775[rip]mov eax, DWORD PTR -12[rbp]add eax, edxmov DWORD PTR g[rip], eaxnopadd rsp, 16pop rbpret.seh_endproc.data.align 4

z.1775:.long 77.ident "GCC: (x86_64-posix-seh-rev1, Built by MinGW-W64

project) 6.3.0"

rip שימו לב שגישה למשתנים סטטיים וגלובליים היא יחסית לאוגרהמשקפת את הכתובת הלינארית של הפקודה הנוכחית.

כפי שמשתמע מהתוכנית הבאה, ככל הנראה כאשר האסמבלרממש פקודה נוסח

mov rax,var1[rip]

Page 17: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

הוו בונה היסט שככל הנראה מביאה בחשבון את המיקם של.var1הפקודה עצמה בנוסף למיקום של

מכיוון שאין סגמנתציה יותר, ומאחר ובכל זאת הכתובות הגלובליות לוקח על עצמו את ההצבעה על שטחיripחייבות להיות יחסיות,

זיכרון.

:ripהתוכנית הבאה נותנת איזה אינדיקציה על ערכו של

// print_rip3.c

#include <stdio.h>

extern unsigned long long int ret_rip();

extern unsigned long long int ret_rip2(unsigned long long int *rip2);

unsigned long long int lea1_rip, lea2_rip, stack_rip;unsigned long long int (*pf)(unsigned long long int *);

int main(){ lea1_rip = ret_rip(); pf = ret_rip; printf("lea1_rip = %llu, hex = %llx\n", lea1_rip, lea1_rip); printf("&ret_rip = %llu, hex = %llx\n", pf, pf); lea2_rip = ret_rip2(&stack_rip); pf = ret_rip2; printf("lea2_rip = %llu, hex = %llx\n", lea2_rip, lea2_rip); printf("&ret_rip2 = %llu, hex = %llx\n", pf, pf);

Page 18: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

printf("stack_rip = %llu, hex = %llx\n", stack_rip, stack_rip); printf("main = %llu, hex = %llx\n", main, main); printf("&stack_rip = %llu, hex = %llx\n", &stack_rip, &stack_rip); printf("&lea1_rip = %llu, hex = %llx\n", &lea1_rip, &lea1_rip); printf("&lea2_rip = %llu, hex = %llx\n", &lea2_rip, &lea2_rip); printf("&pf = %llu, hex = %llx\n", &pf, &pf);

}//main

.file "RET_RIP.C"

.intel_syntax noprefix

.text

.globl ret_rip

.def ret_rip; .scl 2; .type 32; .endef

.seh_proc ret_ripret_rip:.LFB0:

pushrbp.seh_pushreg rbpmov rbp, rsp.seh_setframe rbp, 0.seh_endprologuelea rax, [rip]pop rbpret.seh_endproc.ident "GCC: (x86_64-posix-seh-rev1, Built by MinGW-

W64 project) 6.3.0"

.file "RET_RIP2.C"

.intel_syntax noprefix

Page 19: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

.text

.globl ret_rip2

.def ret_rip2; .scl 2; .type 32; .endef

.seh_proc ret_rip2ret_rip2:.LFB0:

pushrbp.seh_pushreg rbpmov rbp, rsp.seh_setframe rbp, 0.seh_endprologuemov rax, QWORD PTR 8[rbp]mov [rcx], raxlea rax,0[rip]pop rbpret.seh_endproc.ident "GCC: (x86_64-posix-seh-rev1, Built by MinGW-

W64 project) 6.3.0"

פלט ריצה:D:\print_rip>gcc print_rip3.c ret_rip.s ret_rip2.s

D:\print_rip>a.exelea1_rip = 4200315, hex = 40177b&ret_rip = 4200304, hex = 401770lea2_rip = 4200338, hex = 401792&ret_rip2 = 4200320, hex = 401780stack_rip = 4199995, hex = 40163bmain = 4199856, hex = 4015b0&stack_rip = 4225392, hex = 407970

Page 20: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

&lea1_rip = 4225408, hex = 407980&lea2_rip = 4225400, hex = 407978&pf = 4225416, hex = 407988

D:\print_rip>

פשוט אך יעיל. debuggerלמערכת ההרצה הבאה תמחיש את עיקר האמצעים הקיימים:

C:\Users\User\asm64>gcc -g call_id3.c idiv_mod64.s

C:\Users\User\academic\ComArchNew\asm64>gcc -g call_id3.c idiv_mod64.s

C:\Users\User\asm64>gdb a.exeGNU gdb (GDB) 7.11.1Copyright (C) 2016 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. Type "show copying"and "show warranty" for details.This GDB was configured as "x86_64-w64-mingw32".Type "show configuration" for configuration details.For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>.Find the GDB manual and other documentation resources online at:<http://www.gnu.org/software/gdb/documentation/>.For help, type "help".Type "apropos word" to search for commands related to "word"...Reading symbols from a.exe...done.

Page 21: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

(gdb) helpList of classes of commands:

aliases -- Aliases of other commandsbreakpoints -- Making program stop at certain pointsdata -- Examining datafiles -- Specifying and examining filesinternals -- Maintenance commandsobscure -- Obscure featuresrunning -- Running the programstack -- Examining the stackstatus -- Status inquiriessupport -- Support facilitiestracepoints -- Tracing of program execution without stopping the programuser-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.Type "help all" for the list of all commands.Type "help" followed by command name for full documentation.Type "apropos word" to search for commands related to "word".Command name abbreviations are allowed if unambiguous.(gdb) help breakpointsMaking program stop at certain points.

List of commands:

awatch -- Set a watchpoint for an expressionbreak -- Set breakpoint at specified locationbreak-range -- Set a breakpoint for an address rangecatch -- Set catchpoints to catch eventscatch assert -- Catch failed Ada assertionscatch catch -- Catch an exceptioncatch exception -- Catch Ada exceptionscatch exec -- Catch calls to execcatch fork -- Catch calls to fork

Page 22: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

catch load -- Catch loads of shared librariescatch rethrow -- Catch an exceptioncatch signal -- Catch signals by their names and/or numberscatch syscall -- Catch system calls by their names and/or numberscatch throw -- Catch an exceptioncatch unload -- Catch unloads of shared librariescatch vfork -- Catch calls to vforkclear -- Clear breakpoint at specified locationcommands -- Set commands to be executed when a breakpoint is hitcondition -- Specify breakpoint number N to break only if COND is truedelete -- Delete some breakpoints or auto-display expressionsdelete bookmark -- Delete a bookmark from the bookmark listdelete breakpoints -- Delete some breakpoints or auto-display expressionsdelete display -- Cancel some expressions to be displayed when program stopsdelete mem -- Delete memory regiondelete tracepoints -- Delete specified tracepoints---Type <return> to continue, or q <return> to quit---q(gdb) help breakSet breakpoint at specified location.break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]PROBE_MODIFIER shall be present if the command is to be placed in aprobe point. Accepted values are `-probe' (for a generic, automaticallyguessed probe type), `-probe-stap' (for a SystemTap probe) or`-probe-dtrace' (for a DTrace probe).LOCATION may be a linespec, address, or explicit location as describedbelow.

With no LOCATION, uses current execution address of the selectedstack frame. This is useful for breaking on return to a stack frame.

THREADNUM is the number from "info threads".CONDITION is a boolean expression.

Page 23: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

Linespecs are colon-separated lists of location parameters, such assource filename, function name, label name, and line number.Example: To specify the start of a label named "the_top" in thefunction "fact" in the file "factorial.c", use"factorial.c:fact:the_top".

Address locations begin with "*" and specify an exact address in theprogram. Example: To specify the fourth byte past the start function"main", use "*main + 4".

Explicit locations are similar to linespecs but use an option/argumentsyntax to specify location parameters.Example: To specify the start of the label named "the_top" in thefunction "fact" in the file "factorial.c", use "-source factorial.c---Type <return> to continue, or q <return> to quit---q(gdb) list11 int No_Zero_Divide;1213 printf("\nEnter Numerator, Denominator\n:");14 scanf("%lld %lld",&Num, &Denom);15 No_Zero_Divide = idiv_mod64(Num,Denom,&Q,&Rem);16 if (No_Zero_Divide)17 printf("\n %lld div %lld = %lld, mod(%lld,%lld) = %lld\n",18 Num, Denom, Q, Num, Denom, Rem);19 else20 printf("\nError: Zero Divide.\n");(gdb) list 1813 printf("\nEnter Numerator, Denominator\n:");14 scanf("%lld %lld",&Num, &Denom);15 No_Zero_Divide = idiv_mod64(Num,Denom,&Q,&Rem);16 if (No_Zero_Divide)17 printf("\n %lld div %lld = %lld, mod(%lld,%lld) = %lld\n",18 Num, Denom, Q, Num, Denom, Rem);19 else20 printf("\nError: Zero Divide.\n");

Page 24: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

2122 return 0;(gdb) break 15Breakpoint 1 at 0x401593: file call_id3.c, line 15.(gdb) runStarting program: C:\Users\User\academic\ComArchNew\asm64\a.exe[New Thread 5124.0x17fc][New Thread 5124.0x10c]

Enter Numerator, Denominator:10000000 99

Thread 1 hit Breakpoint 1, main () at call_id3.c:1515 No_Zero_Divide = idiv_mod64(Num,Denom,&Q,&Rem);(gdb) print Num$1 = 10000000(gdb) print Denom$2 = 99(gdb) stepidiv_mod64 () at idiv_mod64.s:88 push rbp(gdb) step10 mov rbp, rsp(gdb) step13 mov rbx,rdx(gdb) print $rbp$3 = (void *) 0x61fdd0(gdb) contContinuing.

10000000 div 99 = 101010, mod(10000000,99) = 10[Thread 5124.0x10c exited with code 0][Inferior 1 (process 5124) exited normally](gdb) quit

Page 25: math.haifa.ac.ilmath.haifa.ac.il/.../lectures/lecture09/CArch18.docx · Web viewתוכניות באסמבלי x86_64 תחת MinGcc לצורך הקורס הזה הכי נוח בקומפילר

C:\Users\User\asm64>