源代码test.c
int func(int a, int b);
int m = 10;
int main()
{
int i = 4;
int j = 5;
m = func(i, j);
return 0;
}
int func(int a, int b)
{
int c = 0;
c = a + b;
return c;
}
gcc -S test.c 得到x86-64 汇编代码:在代码中数字往往代表的是地址偏移,如 subq $16, %rsp表示栈指针向下偏移4个寻址宽度, 注释中的“$+数字”为立即数
.file "test.c"
.text
.globl m
.data
.align 4
.type m, @object
.size m, 4
m:
.long 10
----------------------------------
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp @ push rbp into stack, rbp: point to the base of the current stack frame
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp @ rbp = rsp, rsp: stack pointer
.cfi_def_cfa_register 6
subq $16, %rsp @ descend rsp: rsp = rsp - 16
movl $4, -8(%rbp) @ *(rbp - 8) = $4, $4 on the stack
movl $5, -4(%rbp) @ *(rbp - 4) = $5, $5 on the stack
movl -4(%rbp), %edx @ edx = *(rbp - 4) = $5
movl -8(%rbp), %eax @ eax = *(rbp - 8) = $4
movl %edx, %esi @ esi = edx = $5
movl %eax, %edi @ edi = eax = $4
call func @ call: The porcessor pushes the value of the EIP(RIP on 64bit) rigister
@(which contains the offset of the instruction following th CALL instruction)onto the stack
@(for use later as a return-instruction pointer). Then branches to the address of the target operand
movl %eax, m(%rip) @ save the return value: m = eax
movl $0, %eax @ eax = $0
@ Release the stack frame set up by an earlier ENTER instrucion, the LEAVE
@ instruction copies the frame pointer(in the E/RBP register) into the stack
@ pointer register(E/RSP), which releases the stack space allocated to the stack
@ frame. The old frame pointer(the frame pointer for the calling procedure that
@ was saved by the ENTER instrucion)is then popped form the stack into the E/RBP
@ register restroing the calling procedure's stack frame.
leave
.cfi_def_cfa 7, 8
ret @ recover RIP
.cfi_endproc
.LFE0:
.size main, .-main
----------------------------------
.globl func
.type func, @function
func:
.LFB1:
.cfi_startproc
pushq %rbp @ push rbp onto the stack
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp @ rbp = rsp
.cfi_def_cfa_register 6
movl %edi, -20(%rbp) @ *(rbp - 20) = edi, edi($5) onto the stack
movl %esi, -24(%rbp) @ *(rbp - 24) = esi, dsi($4) onto the stack
movl $0, -4(%rbp) @ *(rbp - 4) = $0
movl -20(%rbp), %edx @ edx = *(rbp - 20), namely $5
movl -24(%rbp), %eax @ eax = *(rbp - 24), namely $4
addl %edx, %eax @ eax = edx + eax = $5 + $4 = $9
movl %eax, -4(%rbp) @ *(rbp - 4) = eax, result onto the stack
movl -4(%rbp), %eax @ eax = *(rbp - 4) = $9
popq %rbp @ recover rbp
.cfi_def_cfa 7, 8
ret @ recover the RIP(next instruction of the call funcion)
.cfi_endproc
.LFE1:
.size func, .-func
.ident "GCC: (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0"
.section .note.GNU-stack,"",@progbits
arm-linux-gcc -S test.c 得到armv7a汇编代码:同样在代码中数字往往代表的是地址偏移,如 sub sp, sp, #20表示栈指针向下偏移5个寻址宽度, 注释中的“#+数字”为立即数
.arch armv7-a
.eabi_attribute 28, 1
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 6
.eabi_attribute 34, 1
.eabi_attribute 18, 4
.file "test.c"
----------------------------------------------
.text
.global m
.data
.align 2
.type m, %object
.size m, 4
m:
.word 10
----------------------------------------------
.text
.align 1
.global main
.syntax unified
.thumb
.thumb_func
.fpu vfpv3-d16
.type main, %function
main:
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 1, uses_anonymous_args = 0
push {r7, lr} @ push |r7, lr| into stack ()
sub sp, sp, #8 @ descend sp: sp = sp - 8
add r7, sp, #0 @ r7 = sp + 0
movs r3, #4 @ r3 = 4
str r3, [r7] @ *r7 = r3, namely *(sp + 0) = 4
movs r3, #5 @ r3 = 5
str r3, [r7, #4] @ *(r7 + 4) = r3, namely *(sp + 4) = 5
ldr r1, [r7, #4] @ r1 = *(r7 + 4), namely r1 = *(sp + 4) = 5
ldr r0, [r7] @ r0 = *(r7), namely r1 = *(sp + 0) = 4
bl func(PLT) @ bl: save next instruction address to LR, jump into func
mov r2, r0 @ r2 = r0, namely save func return value to r2
ldr r3, .L3 @ r3 = *(&m-) = *(.L3) = *(.LPIC0 + 4)
.LPIC0:
add r3, pc @ r3 = pc + r3
str r2, [r3] @ *(r3) = r2, namely m = r2 (func return value)
movs r3, #0 @ r3 = 0
mov r0, r3 @ r0 = r3 = 0
adds r7, r7, #8 @ r7 = r7 + 8, namely asscend sp: sp = sp + 8
mov sp, r7 @ sp = r7, namely sp = sp
@ sp needed
pop {r7, pc} @ recover: r7 = r7(in stack), pc = lr
.L4:
.align 2
.L3:
.word m-(.LPIC0+4)
.size main, .-main
---------------------------------------------
.align 1
.global func
.syntax unified
.thumb
.thumb_func
.fpu vfpv3-d16
.type func, %function
func:
@ args = 0, pretend = 0, frame = 16
@ frame_needed = 1, uses_anonymous_args = 0
@ link register save eliminated.
push {r7} @ save orignal r7 into stack
sub sp, sp, #20 @ descend sp: sp = sp - 20
add r7, sp, #0 @ r7 = sp + 0
str r0, [r7, #4] @ *(r7 + 4) = r0, namely *(sp + 4) = 4
str r1, [r7] @ *(r7) = r1, namely *(sp) = #5
movs r3, #0 @ r3 = #0
str r3, [r7, #12] @ *(r7 + 12) = r3, namely *(sp + 12) = 0
ldr r2, [r7, #4] @ r2 = *(r7 + 4), namely r2 = *(sp + 4) = #4
ldr r3, [r7] @ r3 = *(r7), namely r3 = *(sp) = #5
add r3, r3, r2 @ r3 = r3 + r2 = #5 + #4
str r3, [r7, #12] @ *(r7 + 12) = r3, namely *(sp + 12) = #9
ldr r3, [r7, #12] @ r3 = *(r7 + 12) = *(sp + 12) = #9
mov r0, r3 @ r0 = r3 = #9
adds r7, r7, #20 @ r7 = r7 + 20, asscend sp: sp = sp + 20
mov sp, r7 @ sp = r7
@ sp needed
ldr r7, [sp], #4 @ recover orignal r7, pop r7 from the stack: r7 = *(sp), sp = sp + 4, namely sp++
@ this instruction can change the processor state form ARM to Thumb, or from Thumb to ARM, | BX Rm | derive the target state from bit[0] of Rm;
bx lr @ branch and exchange instruction set.
.size func, .-func
.ident "GCC: (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) 7.3.0"
.section .note.GNU-stack,"",%progbits