I could use some help with this code: 4. Analyze the x86-64 assembly given below
ID: 3828033 • Letter: I
Question
I could use some help with this code:
4. Analyze the x86-64 assembly given below.
char_out:
subq $8, %rsp
movsbl %dil, %edi # Parameter 1 in %dil / %edi.
call putchar # putchar is a C function that writes (prints)
addq $8, %rsp # a single char to stdout (the screen).
ret
sub_mystery:
subq $8, %rsp
cmpq $9, %rdi # Parameter 1 in %rdi
ja .L4
addl $48, %edi
movsbl %dil, %edi
call char_out
jmp .L3
.L4:
addl $55, %edi
movsbl %dil, %edi
call char_out
.L3:
addq $8, %rsp
ret
mystery:
pushq %r12
pushq %rbp # Saving registers, not relevant.
pushq %rbx
movq %rdi, %rax # Parameter 1 in %rdi, copy into Local 1,%rax.
movl $1, %ebx # Local 2 in %ebx (or %rbx).
jmp .L8
.L9:
salq $4, %rbx
shrq $4, %rax
.L8:
cmpq $15, %rax
ja .L9
movl $0, %ebp # Local 3 in %ebp/rbp, it's not the base pointer!
jmp .L10
.L11:
movq %rdi, %rax
movl $0, %edx
divq %rbx # Division instruction, divides %rax / %rbx
movq %rdx, %r12 # Remainder is stored in %rdx.
movq %rax, %rdi # Quotient is stored in %rax.
call sub_mystery
addl $1, %ebp
movq %r12, %rdi
shrq $4, %rbx
.L10:
testq %rbx, %rbx
jne .L11
movl %ebp, %eax
popq %rbx # Restoring saved registers, also not relevant.
popq %rbp
popq %r12
ret
For the questions below, when you are asked to write C code suppose that any parameters are named P1, P2, etc., in the order the parameters would be listed in the C code. Suppose the local variables are called L1, L2, etc., in the order they occur in the x86-64 assembly, i.e. %eax (or %rax) is the first local variable.
Be advised: you may derive a perfectly acceptable answer and find that when you compile it you get slightly different assembly code. Minor differences should be expected, so don't tweak your C code trying to replicate the assembly code exactly.
Note: this code has been optimized and doesn't manipulate the stack (much). Some registers represent local variables, while others are parameters, recall which registers hold parameters.
a.[10 points] Write C code for the function that could have yielded the x86-64 assembly code given above for char_out(). This should be a one liner. Your final answer must not include any goto statements!
b.[10 points] Write C code for the function that could have yielded the x86-64 assembly code given above for sub_mystery(). Your final answer must not include any goto statements!
c.[20 points] Write C code for the function that could have yielded the x86-64 assembly code given above formystery(). Your final answer must not include any goto statements!
#include <stdlib.h>
#include <stdint.h>
// Q4A
//
//
//
void char_out(char P1)
{
}
// Q4B
//
//
//
void sub_mystery(uint64_t P1)
{
}
// Q4C
//
//
//
int mystery(uint64_t P1)
{
return 0;
}
Explanation / Answer
a)
size_t process_char(char P1) { return P1 - '0'; // return c – 48 is also fine. }
b)
There is a while loop between lines #3 and #10; arguably #1 is included since that initializes a local variable used in the loop test. We know it's a loop because of the backwards branch in #10; we know it's a while loop because of the unconditional jump in #3 that takes us to the loop test before we enter the body of the loop the first time. The loop test occurs on lines #9 and #10.
size_t use_result(size_t P1, size_t P2) { size_t L1 = 0 size_t L2 = 1; while(L1 < P2) { L2 *= 10; L1++; } return P1 * L2; }
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.