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.