Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

In this assignment, you will \"reverse engineer\" several x86-64 assembly langua

ID: 3840899 • Letter: I

Question

In this assignment, you will "reverse engineer" several x86-64 assembly language functions. The goal is to increase your knowledge of assembly language and help you develop the ability to read assembly language code and understand what it does.

Your task: You will find a file called hw5.s , which contains x64 (assembly language) implementations of 9 functions. They are called f1, f2, f3, etc. I generated hw5.s by running gcc on my own C source code, using the –S and –O2 flags. Your task is to write C implementations of these 9 functions, so that your C code emulates the assembly language versions. Each C function that you write will be counted as correct if your function returns the same value as its assembly language version, provided they are both passed the same parameter(s). The exact way in which your C functions are implemented does not have to match the assembly language code. In other words, if you run gcc on your own C code with -S and -O2, the assembly language produced from your code does not have to be an exact match with mine.

   .file   "hw5sol.c"
   .text
   .p2align 4,,15
   .globl   f1
   .type   f1, @function
f1:
.LFB25:
   .cfi_startproc
   cmpl   %esi, %edi
   je   .L3
   cmpl   %edx, %esi
   je   .L3
   xorl   %eax, %eax
   cmpl   %edx, %edi
   setne   %al
   ret
   .p2align 4,,10
   .p2align 3
.L3:
   xorl   %eax, %eax
   ret
   .cfi_endproc
.LFE25:
   .size   f1, .-f1
   .p2align 4,,15
   .globl   f2
   .type   f2, @function

f2:

.LFB26:
   .cfi_startproc
   addl   %esi, (%rdi)
   ret
   .cfi_endproc
.LFE26:
   .size   f2, .-f2
   .p2align 4,,15
   .globl   f3
   .type   f3, @function
f3:
.LFB27:
   .cfi_startproc
   xorl   %eax, %eax
   testq   %rdi, %rdi
   setg   %al
   ret
   .cfi_endproc
.LFE27:
   .size   f3, .-f3
   .p2align 4,,15
   .globl   f4
   .type   f4, @function
f4:
.LFB28:
   .cfi_startproc
   cmpl   %esi, %edi
   movl   %edi, %eax
   jl   .L14
   .p2align 4,,10
   .p2align 3
.L15:
   subl   %esi, %eax
   cmpl   %eax, %esi
   jle   .L15
.L14:
   rep ret
   .cfi_endproc
.LFE28:
   .size   f4, .-f4
   .p2align 4,,15
   .globl   f5
   .type   f5, @function
f5:
.LFB29:
   .cfi_startproc
   cmpb   $0, (%rdi)
   je   .L19
   addq   $1, %rdi
   xorl   %eax, %eax
   .p2align 4,,10
   .p2align 3
.L18:
   addq   $1, %rdi
   addl   $1, %eax
   cmpb   $0, -1(%rdi)
   jne   .L18
   rep ret
.L19:
   xorl   %eax, %eax
   ret
   .cfi_endproc
.LFE29:
   .size   f5, .-f5
   .p2align 4,,15
   .globl   f6
   .type   f6, @function
f6:
.LFB30:
   .cfi_startproc
   movzbl   (%rsi), %edx
   movq   %rdi, %rax
   testb   %dl, %dl
   je   .L23
   movl   $1, %ecx
   xorl   %r9d, %r9d
   jmp   .L22
   .p2align 4,,10
   .p2align 3
.L25:
   movq   %rcx, %r9
   movq   %r8, %rcx
.L22:
   movb   %dl, (%rax,%r9)
   movzbl   (%rsi,%rcx), %edx
   leaq   1(%rcx), %r8
   testb   %dl, %dl
   jne   .L25
.L21:
   movb   $0, (%rax,%rcx)
   ret
.L23:
   xorl   %ecx, %ecx
   jmp   .L21
   .cfi_endproc
.LFE30:
   .size   f6, .-f6
   .p2align 4,,15
   .globl   f7
   .type   f7, @function
f7:
.LFB31:
   .cfi_startproc
   cmpb   $0, (%rdi)
   movq   %rdi, %rax
   je   .L32
   leaq   1(%rdi), %rdx
   xorl   %r8d, %r8d
   .p2align 4,,10
   .p2align 3
.L28:
   movq   %rdx, %r9
   addq   $1, %rdx
   addl   $1, %r8d
   cmpb   $0, -1(%rdx)
   jne   .L28
.L27:
   movzbl   (%rsi), %ecx
   testb   %cl, %cl
   je   .L29
   movslq   %r8d, %r9
   xorl   %edx, %edx
   addq   %rax, %r9
   .p2align 4,,10
   .p2align 3
.L31:
   movb   %cl, (%r9,%rdx)
   addq   $1, %rdx
   addl   $1, %r8d
   movzbl   (%rsi,%rdx), %ecx
   testb   %cl, %cl
   jne   .L31
   movslq   %r8d, %r8
   leaq   (%rax,%r8), %r9
.L29:
   movb   $0, (%r9)
   ret
.L32:
   movq   %rdi, %r9
   xorl   %r8d, %r8d
   jmp   .L27
   .cfi_endproc
.LFE31:
   .size   f7, .-f7
   .p2align 4,,15
   .globl   f8
   .type   f8, @function
f8:
.LFB32:
   .cfi_startproc
   testl   %esi, %esi
   leal   1(%rsi), %edx
   movl   $1, %eax
   jle   .L36
   .p2align 4,,10
   .p2align 3
.L40:
   movl   %eax, (%rdi)
   addl   $1, %eax
   addq   $4, %rdi
   cmpl   %edx, %eax
   jne   .L40
.L36:
   rep ret
   .cfi_endproc
.LFE32:
   .size   f8, .-f8
   .p2align 4,,15
   .globl   f9
   .type   f9, @function
f9:
.LFB33:
   .cfi_startproc
   cmpl   $1, %esi
   jle   .L45
   movl   (%rdi), %eax
   cmpl   %eax, 4(%rdi)
   jl   .L47
   leal   -2(%rsi), %eax
   addq   $8, %rdi
   leaq   (%rdi,%rax,4), %rdx
   jmp   .L43
   .p2align 4,,10
   .p2align 3
.L44:
   movl   (%rdi), %eax
   addq   $4, %rdi
   cmpl   -8(%rdi), %eax
   jl   .L47
.L43:
   cmpq   %rdx, %rdi
   jne   .L44
.L45:
   movl   $1, %eax
   ret
   .p2align 4,,10
   .p2align 3
.L47:
   xorl   %eax, %eax
   ret
   .cfi_endproc
.LFE33:
   .size   f9, .-f9
   .ident   "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-4)"
   .section   .note.GNU-stack,"",@progbits

Explanation / Answer

The tui (content UI) we appeared in address parts your session into sheets for at the same time seeing the C source, gathering interpretation, and additionally current enroll state. The gdb summon design <argument> begins tui mode. The contention determines which sheet you need (src, asm, regs, or split). Tui mode is super-helpful for following execution and watching what is occurring with code/enlists as you stepi. Periodically, tui trips itself and distortions the show. The gdb summon revive now and then attempts to tidy it up. In the event that things get truly insane, ctrl-x a will exit tui mode and return you to normal non-graphical gdb.
Perusing and following gathering in gdb. Perused the C code in trace.c. Gather the program and keep running in gdb. Utilize the gdb orders from the past exercise to set breakpoints, dismantle, stepi through the get together, print registers, et cetera to answer the accompanying inquiries.
In the my_variables work:
Where is arr being put away? How are the qualities in arr introduced? What happened to the strlen approach the string consistent to init the last cluster component?
What directions were transmitted to process the esteem relegated to tally? What does this educate you concerning the sizeof administrator?
Utilize the gdb charge show aggregate to set up an auto-show expression for the variable aggregate and single-stride through the capacity. At begin and end of the capacity, gdb reports that aggregate has been <optimized out> however amid the directions where the esteem is "live", its esteem will be appeared. Utilize the dismantling to figure the area where aggregate is being kept and for what scope of guidelines it is live. What other way might you be able to see the live an incentive amid execution without referencing it by name?
Stop at the capacity begin and utilize the gdb order information local people to demonstrate the neighborhood factors. Contrast this rundown with the revelations in the C source. You'll see a few factors are appeared with qualities ("live"), some are <optimized out>, however others don't appear by any means. Take a gander at the dismantling to make sense of what happened to these altogether missing factors. How does gdb react when you solicit it to print the incentive from one of the unlisted factors? Imagine a scenario where you attempt to set its esteem. Venture through the capacity rehashing the data local people order to watch which factors are inhabit each progression. Look at the dismantling to clarify why there is no progression at which both aggregate and squared are live.
In the u_arith and s_arith capacities:
These capacities summon same grouping of number juggling operations however vary in the signedness of the operands. Deliberately think about the dismantling for the two capacities.
The initial three C proclamations utilizing include, subtract, and increase order into the very same gathering succession for both capacities. How it is conceivable that these guidelines do the right thing for both unsigned and marked number juggling?
The branch guideline radiated for the if articulation is diverse relying upon the signedness of the operand - why? For what qualities will the way taken vary because of the distinction in branch? Set a breakpoint before the cmp explanation and change the estimation of enroll being contrasted with one of those qualities and stepi from that point to check the distinction in ways taken for unsigned versus marked.
While doing a right-move, does gcc emanate a number juggling (sar) or consistent (shr) move? Does it change whether the sort is marked or unsigned?
To separate by 2, what direction is utilized for unsigned? For marked, the get together arrangement is more mind boggling. Follow through by hand or stepi in gdb and clarify what the succession is doing and why it contrasts from the unsigned figuring.
In the for_loop, while_loop and dowhile_loop capacities:
To begin with, read the C code for the three circle variations. Under which conditions are these circles anticipated that would have a similar conduct and when will they vary?
Presently look at the get together. Two of the circles have precisely the same grouping - which two? How does the gathering of the third circle contrast from the other two? Why does it contrast?
Set a breakpoint on circles and change the estimation of the parameter n being passed to the three calls to such an extent that the circle results will contrast. Proceed from that point and see what is printed.
Investigating C arrangement to get together. A fun instrument for researching C to asm is the GCC Explorer, an online "intelligent compiler". (Much obliged, Josh K, for sharing!) Use the connection https://godbolt.org/g/fHoZ7S designed to utilize the myth's adaptation of GCC (4.8.x) and the compiler banners from the CS107 makefiles. You can enter some C code, change it a bit, and instantly watch how those progressions are reflected in the get together. The apparatus is doing likewise errands you could do on myth utilizing gcc/gdb, however in a brisk exploratory setting. Here are a couple investigations to attempt:
The lea guideline permits two includes and an increase by steady 1, 2, 4 or 8 to be stuck into one direction. It was intended for address number juggling, yet the math is perfect with standard whole number operations and it is regularly utilized by compiler to do an effective include/increase combo. Sort in a basic sum(x, y) work that takes two whole number contentions and returns their entirety. Take a gander at the get together and you'll note it issued a lea rather than the normal include. Fascinating! Change the capacity to return x + 2*y or x + 8*y - 17 and perceive how the lea can adjust. On the off chance that you attempt return x + 3*y it will never again fit the example for the lea, what does the compiler use?
Duplicate is a somewhat costly operation and the compiler will do its darnedest to utilize a combo of include, move, or lea. Sort in a basic scale(x) work that takes one number and returns the contention increased by consistent 2. What direction does the compiler use for the calculation? Shouldn't something be said about an increase by 8 or 16 or 256? Presenting a unique defense for forces of 2 is maybe obvious yet what does it accomplish for increase by 3 or 17 or 25? Test to discover a whole number consistent C with the end goal that C*x is communicated as a genuine imul guideline.
Figuring out. The program babybomb requests information and utilizations it to make a call to the capacity secret with expectations of getting an effective return esteem. What sort of info is important to win at this amusement? How about we investigate this puzzle! Open the mystery.s document to see the get together and after that utilization gdb stepi through the execution of a call to riddle and watch its execution. When you see how it works, offer contribution to the program that will breeze through the test and win. There are numerous approaches to win - attempt to discover no less than two distinct ones. You're en route to handling parallel bomb!
Verify with TA
Before you leave, make sure to present your checkoff sheet and have your lab TA dropped by and affirm so you will be legitimately credited. In the event that you don't complete the process of everything before lab is over, we unequivocally urge you to complete the rest of your own. Twofold check your advance with self check.