X86 Assembly Language Learning Book (2) This is the author's learning notes in the process of learning the X86 assembly, it is inevitable to have errors and omissions, welcome to correct. The author will modify the error at any time and publish the new version on its own Blog site. Strictly speaking, this document is more focused on the knowledge of C language and C compiler. If it involves basic assembly language, you can refer to the relevant document. Since the X86 assembly language study (1) Since the author's blog, I have received a lot of netizens' affirmation and encouragement, and I also have a enthusiastic netizen pointed out that the error has been updated after the error has been discovered in the document. BLOG. Previous article leads the following concepts: Stack Frame Stack Framework and SFP Stack Frame Pointer Stack ALIGNED Stack Other Calling Convertion Call Answer and ABI (Application Binary Interface) Binary Interface This chapter will Through further experiments, we will understand these concepts in depth. If you still don't understand these concepts, you can refer to X86 assembly language learning incoming (1).
1. Stack allocation of local variables The upper article has been analyzed with the simplest C program. Here we analyze how the C compiler handles the allocation of local variables, give this, give this procedure: #vi test2.c Int Main ) {INT i; INT j = 2; i = 3; i = i; returni j;} Compile the program, generate binary files, and use MDB to observe the status of Stack in the run: #gcc test2 .c -o test2 # mdb test2 loading modules: [libc.so.1]> main :: dis be: pushl% EBP Main 1: MAIN 1,% EBP; Main to Main 1, create Stack Frame Main 3: Subl $ 8,% ESP; for local variables I, J assign the stack space, and guarantee the 16-byte alignment main 6: Andl $ 0xF0,% ESP Main 9: MOVL $ 0,% EAX Main 0xe: Subl% Eax,% ESP; Main 6 to Main 0xe, Keep the stack 16 bytes MAIN 0x10: MOVL $ 2, -8 (% EBP); initializing the local variable J is 2 main 0x17: Movl $ 3, - 4 (% EBP); assigning a local variable I to 3 main 0x1e: LEAL-4 (% EBP),% EAX; put the address of local variable i into the EAX register main 0x21: Incl (% EAX); i main 0x23: MOVL-8 (% EBP),% EAX; loads j's value into Eax Main 0x26: addl -4 (% EBP),% EAX; i j, Enter Eax, as return value main 0x29: Leave; revoked Stack frame main 0x2a: return; main function returned>> main 0x10: b; set breakpoint in address main 0x10> Main 0x1e: b; in main 0x1e Set breakpoint> main 0x29: b; in main 0x1e set breakpoint> main 0x2a: b; 4 commands in MAIN 0x1e Set the following MDB below, the middle is separated by semicolons The meaning of the command is given in the comment:>: r; Specify the format output 16 bytes of stack content ( Is 3 0x8047db8: 0x8047dd8; This is _start of SFP, 4 bytes 0x8047dbc: _start 0x5d; EIP after it is returned _start 0x8047dc0: 1 0x8047dc4: 0x8047de4 0x8047dc8: 0x8047dec 0x8047dcc: _start 0x35 0x8047dd0: _fini 0x8047dd4: ld.so.1`atexit_fini 0x8047dd8: 0 0x8047ddc: 0 0x8047DE0: 1 0x8047de4: 0x8047eb4 0x8047de8: 0 0x8047dec: 0x8047eba 8047db8; this is the value of Main Current EBP register, the sfp 0 of Main; EAX value, current 0> : C; Atexit_fini 0x8047dd8: 0 0x8047ddc: 0 0x8047de0: 0x8047de4: 0x8047eb4 0x8047de8: 0 0x8047dec: 0x8047eba 8047db: 0x8047eba 8047db8; this is the value of the origin of the EBP register, that is, the SFP 6 of Main; Eax's value, the return value of the function, current 6> : C; 0x5d once stored at addresses 0x8047dbc 0x8047dc0: 0x8047dc0: 1; main has been returned, _start 0x5d has been ejected 0x8047dc4: 0x8047de4 0x8047dc8: 0x8047dec 0x8047dcc: _start 0x35 0x8047dd0: _fini 0x8047dd4: ld.so.1`atexit_fini 0x8047dd8: 0; an SFP _start directed content is 0, the entry procedure is proven _start 0x8047ddc: 0 0x8047de0: 1 0x8047de4: 0x8047eb4 0x8047de8: 0 0x8047dec: 0x8047eba 0x8047df0: 0x8047ed6 0x8047df4: 0x8047edd 0x8047df8: 0x8047ee4 0x8047dfc: 0x8047ef3 8047dd8; _start of SFP, before Stored at address 0x8047db8, Main STACK FRAME recovered 6; EAX value is 6, or the return value of the main function> Observe and analysis of registers and stacks at runtime at the MDB, you can draw local variables in the stack Access and allocation and release methods: 1. Distribution of local variables, can minus the number of bytes of bytes of bytes of bytes of bytes through ESP,% ESP 2. The release of local variables can be accessed by the Leave instruction Leave 3. Access to the partial variable, can minus the offset MOVL-8 (% EBP),% EAX ADDL-4 (% EBP),% EAX Question: When How to make a stack when there is more than 2 partial variables? In the last article, mention SUBL $ 8,% ESP statement except for the assignment stack space, there is still a role to the stack. So in this case, since I and J are 8 bytes, if there is more than 2 local variables, how to meet spatial allocation and stacks at the same time? 2. The stack assignment of more than two local variables In the previous C program, increase the local variable definition k, the procedures are as follows: # vi test3.c int main () {INT i, j = 2, k = 4; i = 3; i = i; k = i j k; return K;} After compiling the program, use MDB disassembly with the following results: # GCC Test3.c -o test3 # mdb test3 loading modules: [libc .sso.1]> main :: disame: Pushl% EBP Main 1: MAIN% ESP,% EBP; Main to Main 1, create Stack Frame Main 3: SUBL $ 0x18,% ESP; for local variable I , J, K assigns the stack space, and guarantee the 16-byte alignment main 6: Andl $ 0xf0,% ESP Main 9: MOVL $ 0,% EAX Main 0xe: Subl% EAX,% ESP; Main 6 to Main 0xE, again to ensure the stack 16 bytes MAIN 0x10: MOVL $ 2, -8 (% EBP); j = 2 main 0x17: MOVL $ 4, -0xc (% EBP); k = 4 main 0x1e: MOVL $ 3 , -4 (% EBP); i = 3 main 0x25: LEAL-4 (% EBP),% EAX; load i's address to Eax Main 0x28: incl (% EAX); i main 0x2a: Movl -8 (% EBP),% EAX; load J's value Enter Eax Main 0x2d: MOVL-4 (% EBP),% EDX; load i to EDX Main 0x30: addl% EAX,% EDX; J i, the result is deposited in EDX Main 0x32: Leal -0xc (% EBP),% EAX; put K's address into Eax Main 0x35: addl% EDX, (% EAX); i j k, result deposit in EBP-0XC K, MAIN 0x37 : MOVL -0XC (% EBP),% EAX; load K's value into Eax, as return value main 0x3a: Leave; revoke Stack Frame Main 0x3b: return; main function returns> Question: Why is the 3 variables allocated 0x18 bytes of stack space? At 2 variables, the instructions of the allocation stack space are: Subl $ 8,% ESP, when 3 local variables, the commands that assign stack spaces are: SUBL $ 0x18,% ESP 3 integer variables only need 0xc word Festival, why do you actually allocate 0x18 bytes? The answer is: Keep the 16-byte stack alignment. In the X86 assembly language learning incoming (1), it has explained that the default compilation of GCC is to be 16-bytes stack alignment, SUBL $ 8,% ESP will make the stack 16 bytes, while 8-byte space can only meet 2 Local variables, if the 4 bytes meet the third local variable, the stack address is no longer 16-byte aligned, while the closer of the space needs and keeps the 16-byte stack alignment is 0x18. If each, each define a 50-byte and 100-byte character array, in this case, how many stack space actually assigned? The answer is 0x8 0x40 0x70, which is 184 bytes. Let's verify the following: # vi test4.c int main () {char str1 [50]; char str2 [100]; return 0;} # mdb test4 loading modules: [libc.so.1]> main :: disgu : Pushl% EBP Main 1: MOVL% ESP,% EBP Main 3: Subl $ 0xB8,% ESP; for two character array assignment stack space, while guarantees 16 bytes Align Main 9: Andl $ 0xF0,% ESP Main 0xc: MOVL $ 0,% EAX Main 0x11: Subl% EAX,% ESP Main 0x13: MOVL $ 0,% EAX Main 0x18: Leave Main 0x19: RET> 0xB8 = D; 16 Encorptor 10 184> 0x40 0x70 0x8 = x; expression calculation, result is specified as 16 credit B8> Problem: What is the stack allocation order when defining multiple local variables? The order in which the local variable stack assignment is in the order of the variable declaration, the variables declared in the same line are in the order from left to right, in Test2.c, the variable declaration is as follows: INT I, J = 2, k = 4; the result of the anti-assessment: MOVL $ 2, -8 (% EBP); J = 2 MOVL $ 4, -0xc (% EBP); K = 4 MOVL $ 3, -4 (% EBP); i = 3 It is difficult to see that the location in the stack of i, j, k is shown below: -------------------------- -- -> High address | EIP (_Start function return address) | -------------------------- | EBP (_Start function EBP) | <------ Main function EBP pointer (ie SFP frame pointer) ------------------------- - | I (EBP-4) | ---------------------------- | J (EBP-8) | - --------------------------- | K (EBP-0XC) | ------------- --------------- ----> Low address Figure 2-13. Small knot adopts several test procedures to further understand the distribution of local variables in the stack and Released and position, and review the following concepts involved in the last article: SFP Stack Frame Pointer Stack Aligned Stack The MDB tools provided by Solaris are visually observed in the MDB tools provided by Solaris, and the creation and revoking of Stack Frames, according to the content of the legend (Figure 2-1) And Figure 1-1), you can more clearly understand the Stack Layer in the IA32 architecture in memory. Related Documents: X86 Compilation Language Learning Instruction (1) Development Environment on Solaris Installation and Settings Linux AT & T Assembly Language Development Guide ELF Dynamic Resolution Symbol Process (Revised) Follow: Solaris 10's 10 new Change Author Blog: http://blog.9cbs.net/yayong/