How do I determine the initial register values being utilized in Intel x86 assembly code?

Viewed 613

I am working on counting the number of assembly instructions in a disassembled code (add,sub,jmp, etc.). I also have to consider conditions that might cause loops/jumps requiring me to repeatedly count a set of instructions. Therefore, I have to record the values of registers, so when I encounter a condition like "jne", I'll know whether the code jumped or if I can just continue parsing the disassembled code.

I am currently confused on the initial values of registers like (edx, eax, rbp, rsp, etc.). I used objdump to dump all the assembly code, and I can see that in my disassembled <main> function, the first line of assembly code is:

push rbp

mov rbp, rsp

sub rsp, 0xdb0

I have no idea where rbp is initialized. When I did a control F for "rbp", I see the first thing that pops up is the "rex.WRX push rbp" instruction. Does this initialize rbp to 0?

I am also confused on where the assembly code starts from. I originally thought it started from <main>, but I also see other functions like <start> and <init>.

Any clarifications would be appreciated!

1 Answers

Objdump will give you only static disassembly of an executable. To get the run time trace of your program you can use tools like Intel Pin. There is an itrace.so tool in ManualExample folder of pin distributions that you can simply use to get the run time trace of a program.

Path-to-pin-folder/pin -t pin-tool-name-with-path -- binary-to-instrument

Pin framework also let you to log content of different registers and content and address of program variables. See PIN manual for examples and how to write your own tools. You can always modify the content of an existing example to modify it for your needs. To write a completely new pin tool, you should use the pin tool template in MyPinTool directory.

"push rbp and other instructions at start of a function". During a program execution a series of functions are called. Every function shares the registers and stack. Every function uses a portion of stack for its local variables. When a function releases the stack location are free to be used by other subsequent functions. Freeing the memory is simple, modify the stack top (rbp) value. Using a stack ensures that same set of memory locations can be used by local variables of many functions, reducing memory requirement.

main() is the first user written function that is called during execution of a program. A set of additional functions which are not part of the original program, __start(), __fini, and likes are also there as part of a program executable which are usually not defined by users. They are OS specific and are added by the compilers. Some of them are called before and some after the execution of user program, for initialization and house keeping.

Related