Platform: JZ2440 development board --CPU: S3C2440 (ARM920)
Foreword
The previous exercise, using a C language program LED lights, this exercise will do an analysis of the disassembled file program, and tap the knowledge of them.
Preliminaries
ARM register
ATPCS (arm-thumb Procedure Call Standard)
purpose
In order for the C language and assembler designated call rules can call each other, as long as the language used to comply with the standard, they can call each other and running.
content
1. Register usage rules
A register can be used in a total of 16 ARM mode as R0-R15.
Passing parameters R0-R3, Functions after use can not restore the original value.
R4-R11 local variables, if the original value of the need to save and restore the original value in the return value.
R12 subroutine as scratch register, alias IP, used to store other registers do stack saving, etc., as described in mov ip, sp operation
R13 as the stack pointer, SP, this is all architectures, including ARM, IA-32 are present in the register, you need to save and restore accurate, otherwise it will affect the normal operation, also known as the stack to maintain balance.
R14 saved return address, LR, bl instruction will return to the address stored value, common usage is: lr save the address on the stack to save, and then when the function exits lr assigned to the pc register, run to achieve the purpose of the return address.
Address R15, PC, program counter, the register at the address for the program to be executed, based on the ARM pipeline mechanism, under the three-stage pipeline case, PC will point to the currently running instruction address +8 address. The other register is used to save the Program Status bits, such as overflow, carry, 0 and the like. PC can not be used in addition to the above described functions, the IA-32 architecture with the difference that the register may be assigned directly, but only indirectly modify the IA-32 and the like by jmp instruction.
2. The data stack usage rules
The provisions of the growth direction of a good stack, this usually is descending stack. In descending stack, for example, when the stack, sp needs db (decrease before) or da (decrease after), sp needs ia (increase after) or ib (increase before), these are the need of unity to let the stack when the stack Normal use.
3. parameter passing rules
Function call, passing parameters R0-R3, the number of parameters exceeds 4, the remaining parameters passed by the stack, and returns the value returned is the use of R0-R3.
4. save and restore rule
It will destroy some of the values stored in registers or other function calls, the need for site protection in order to function on a normal operation after the function returns. We must restore the site in accordance with the agreed rules corresponding function exits. Functions currently used registers need to use the register in accordance with the order (high-order register to the stack, such as R15) stack, when the stack is then in turn can be de-stacked.
analysis
led.elf: file format elf32-littlearm
Disassembly of section .text:
00008074 <_start>:
8074: e3a00000 mov r0, #0 ; 0x0
8078: e5901000 ldr r1, [r0]
807c: e5800000 str r0, [r0]
8080: e5902000 ldr r2, [r0]
8084: e1520000 cmp r2, r0
8088: e59fd00c ldr sp, [pc, #12] ; 809c <.text+0x28>
808c: 03a0da01 moveq sp, #4096 ; 0x1000
8090: 05801000 streq r1, [r0]
8094: eb000001 bl 80a0 <main> //bl跳转main,返回地址lr=8098
00008098 <halt>:
8098: eafffffe b 8098 <halt>
809c: 40001000 andmi r1, r0, r0
000080a0 <main>:
80a0: e1a0c00d mov ip, sp
80a4: e92dd800 stmdb sp!, {fp, ip, lr, pc}
80a8: e24cb004 sub fp, ip, #4 ; 0x4
80ac: e24dd008 sub sp, sp, #8 ; 0x8
80b0: e3a03456 mov r3, #1442840576 ; 0x56000000
80b4: e2833050 add r3, r3, #80 ; 0x50
80b8: e50b3010 str r3, [fp, #-16]
80bc: e3a03456 mov r3, #1442840576 ; 0x56000000
80c0: e2833054 add r3, r3, #84 ; 0x54
80c4: e50b3014 str r3, [fp, #-20]
80c8: e51b2010 ldr r2, [fp, #-16]
80cc: e51b3010 ldr r3, [fp, #-16]
80d0: e5933000 ldr r3, [r3]
80d4: e3c33c3f bic r3, r3, #16128 ; 0x3f00
80d8: e5823000 str r3, [r2]
80dc: e51b2010 ldr r2, [fp, #-16]
80e0: e51b3010 ldr r3, [fp, #-16]
80e4: e5933000 ldr r3, [r3]
80e8: e1e03003 mvn r3, r3
80ec: e2033c15 and r3, r3, #5376 ; 0x1500
80f0: e1e03003 mvn r3, r3
80f4: e5823000 str r3, [r2]
80f8: e51b2014 ldr r2, [fp, #-20]
80fc: e51b3014 ldr r3, [fp, #-20]
8100: e5933000 ldr r3, [r3]
8104: e3c33070 bic r3, r3, #112 ; 0x70
8108: e5823000 str r3, [r2]
810c: e3a03000 mov r3, #0 ; 0x0
8110: e1a00003 mov r0, r3
8114: e24bd00c sub sp, fp, #12 ; 0xc
8118: e89da800 ldmia sp, {fp, sp, pc}
Disassembly of section .comment:
00000000 <.comment>:
0: 43434700 cmpmi r3, #0 ; 0x0
4: 4728203a undefined
8: 2029554e eorcs r5, r9, lr, asr #10
c: 2e342e33 mrccs 14, 1, r2, cr4, cr3, {1}
10: Address 0x10 is out of bounds.
Disassembly above, it is assumed in this embodiment nandflash activated, sp is set to 4096. BL jump to the main boot file main function in C program, this time lr register contains the address 8098 returned.
After entering the main, first save the need to preserve the site, you will need to use a register stack save
80a0: e1a0c00d mov ip, sp //fp=? ip=4096 sp=4096 lr=8098 pc=80A8
80a4: e92dd800 stmdb sp!, {fp, ip, lr, pc}
stack address | value | comment | ||
4092 | 0x80A8 | pc | ||
4088 | 0x8098 | lr | ||
4084 | 4096 | ip=old sp | ||
4080 | unknowvalue | fp | <-sp |
Fp is then adjusted to the stored first address field, based on the use of the back fp, fp registers and I believe that is the IA-32 EBP register architecture similar effect, as the reference stack frames, adding the offset value on the basis of addressing any variable stack frame. Then sp - 8 is a compilation of common memory it is a local variable, which point is the same IA-32 architecture, which corresponds to the C program is our two registers point pointers.
80a8: e24cb004 sub fp, ip, #4 ; 0x4 //fp = ip - 4 =4096-4 =4092
80ac: e24dd008 sub sp, sp, #8 ; 0x8 //sp =sp -8 = 4072 //两个int 局部变量
stack address | value | comment | ||
4092 | 0x80A8 | pc | ||
4088 | 0x8098 | lr | ||
4084 | 4096 | ip=old sp | ||
4080 | unknowvalue | fp | ||
4076 | ||||
4072 | <-sp |
After the memory to fp reference addressed to the address of the memory it just assignment register value
80b0: e3a03456 mov r3, #1442840576 ; 0x56000000//r3=0x56000000
80b4: e2833050 add r3, r3, #80 ; 0x50 //r3=0x56000050
80b8: e50b3010 str r3, [fp, #-16] //fp - 16 = 4092 - 16 = 4076
80bc: e3a03456 mov r3, #1442840576 ; 0x56000000
80c0: e2833054 add r3, r3, #84 ; 0x54
80c4: e50b3014 str r3, [fp, #-20]
stack address | value | comment | ||
4092 | 0x80A8 | pc | ||
4088 | 0x8098 | lr | ||
4084 | 4096 | ip=old sp | ||
4080 | unknowvalue | fp | ||
4076 | 0x56000050 | |||
4072 | 0x56000054 | <-sp |
Followed by a program located on a local variable processing corresponds to C programs can clearly understand, no knowledge, and therefore are not described.
//*pGPFCON &= ~((3<<8) | (3<<10) | (3<<12));
80c8: e51b2010 ldr r2, [fp, #-16]
80cc: e51b3010 ldr r3, [fp, #-16]
80d0: e5933000 ldr r3, [r3]
80d4: e3c33c3f bic r3, r3, #16128 ; 0x3f00
80d8: e5823000 str r3, [r2]
//*pGPFCON |= ~((1<<8) | (1<<10) | (1<<12));
80dc: e51b2010 ldr r2, [fp, #-16]
80e0: e51b3010 ldr r3, [fp, #-16]
80e4: e5933000 ldr r3, [r3]
80e8: e1e03003 mvn r3, r3
80ec: e2033c15 and r3, r3, #5376 ; 0x1500
80f0: e1e03003 mvn r3, r3
80f4: e5823000 str r3, [r2]
//*pGPFDAT &=~((1<<4) | (1<<5) | (1<<6));
80f8: e51b2014 ldr r2, [fp, #-20]
80fc: e51b3014 ldr r3, [fp, #-20]
8100: e5933000 ldr r3, [r3]
8104: e3c33070 bic r3, r3, #112 ; 0x70
8108: e5823000 str r3, [r2]
The last is the return value of the assignment, according to ATPCS shows that the R0 register is used here as a return value stored in the register, the return value is 0, where disassembly any special meaning not through R3 as an intermediary, if the compiler should be smart point the optimized away here.
810c: e3a03000 mov r3, #0 ; 0x0
8110: e1a00003 mov r0, r3
Thus, the end of the main function is executed, the address lr ready to return to the point, in which case the need to restore the saved value to the register in the stack, while restoring sp. First assigned to the local variable stack space recovery, where only the upper end of the recovery point sp local variable assigned address, do not heap appropriate recovery operation, because of the need to use the next memory address bound It will be covered, and therefore do not require additional processing.
8114: e24bd00c sub sp, fp, #12 ; 0xc //局部变量退栈
stack address | value | comment | ||
4092 | 0x80A8 | pc | ||
4088 | 0x8098 | lr | ||
4084 | 4096 | ip=old sp | ||
4080 | unknowvalue | fp | <-sp | |
4076 | 0x56000050 | |||
4072 | 0x56000054 |
Corresponding to the beginning of the last ldmia stmdb, the data stored in the stack is returned to the register {}. Comparison tables can be seen on a stack, the stack fp saved will be restored to the registers fp, ip preserve the value of old sp, thereby sp sp to return to the main pre-call, save the last lr is stored in the return address, just pc restore to register, so the next instruction executed pc address points to the return value, the function main normal exit. (ldmia involving the assignment to sp, but will still continue to run sp ia normal, because the operation instruction ia is tmp sp do the operation details, refer to https://blog.csdn.net/G_METHOD/article/ details / 104126283 described for the ldm)
8118: e89da800 ldmia sp, {fp, sp, pc}
stack address | value | comment | ||
4092 | 0x80A8 | pc | <-sp | |
4088 | 0x8098 | lr ======》pc | ||
4084 | 4096 | ip=old sp===》sp | ||
4080 | unknowvalue | fp=======》fp | ||
4076 | 0x56000050 | |||
4072 | 0x56000054 |