1)
int add(int i, int j)
{
return i + j;
}
int main()
{
int a = 1;
int b = 7;
a = add(a, b);
printf("%d\n",a);
}
汇编代码:
.file "ex3.c"
.text
.globl add
.type add, @function
add:
.LFB0:
.cfi_startproc
pushq %rbp # rbp入栈, 把rbp里的值压入堆栈。即当前rsp-4出的值变为rbp的值,rbp本身的值不变。
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp # rsp 的值给rbp
.cfi_def_cfa_register 6
movl %edi, -4(%rbp) # edi 给rbp地址-4, 1
movl %esi, -8(%rbp) # esi 给rbp地址-8, 7
movl -4(%rbp), %edx # 又把1 给 edx
movl -8(%rbp), %eax # 又把7 给 eax
# movl $1, %edx # 又把1 给 edx
# movl $7, %eax # 又把7 给 eax
addl %edx, %eax # eax=eax+edx
popq %rbp # 是把当esp指向的栈中的值(即之前push rbp进栈的rbp的值)赋给rbp
# 并且esp+4(dx的值改变,esp在pop之前指向的地方的值不变,还是之前ax进栈后的值,即堆栈里的那个值不会自动清零)
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size add, .-add
.section .rodata
.LC0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp # 为什么知道是16 byte?
# movl $1, -8(%rbp) # 第1个参数
movl $1, 8(%rsp)
# movl $7, -4(%rbp) # 第2个参数
movl $7, 12(%rsp)
movl -4(%rbp), %edx # 把7给edx
movl -8(%rbp), %eax # 把1给eax
movl %edx, %esi # edx 给esi, 7, 不是什么变址寄存器啊
movl %eax, %edi # eax 给edi, 1
call add
# movl %eax, -8(%rbp)
# movl -8(%rbp), %eax
movl %eax, %esi
leaq .LC0(%rip), %rdi
# movl $0, %eax
call printf@PLT
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size main, .-main
.ident "GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0"
.section .note.GNU-stack,"",@progbits
大部分看得懂,小部分不知道什么意思。汇编是可以修改的,跟C语言差不多。
感觉Fortran更加麻烦一些。
.file "b3.frac.f90"
.text
.p2align 4,,15
.globl frac_
.type frac_, @function
frac_:
.LFB0:
.cfi_startproc
# frac(k,gij,b,u,i,j)
movl (%rdi), %r10d # k, 第一个参数。r10d为r10的低32位,因为k是整数
movsd (%rsi), %xmm0 # gij, 第2个参数,加载到xmm0的低64位。
testl %r10d, %r10d # test只是进行按位与,不进位。判断k是否为0。
jle .L10 # 算是一个技巧性的预处理,如果k==0,就直接结束。确实有为0的。
pushq %r12 # 被调用者保存
.cfi_def_cfa_offset 16
.cfi_offset 12, -16
pushq %rbp # 被调用者保存
.cfi_def_cfa_offset 24
.cfi_offset 6, -24
leal 1(%r10), %r11d
pushq %rbx
.cfi_def_cfa_offset 32
.cfi_offset 3, -32
movslq (%r9), %rax
movslq %r10d, %r9
imulq $1681, %r9, %rbx
movslq (%r8), %r12
leaq (%rax,%rax,4), %rdi
leaq (%rax,%rdi,8), %rbp
leaq (%rbx,%rbp), %rdi
addq %r12, %rdi
cmpl $2, %r10d
leaq (%rcx,%rdi,8), %rax
jle .L6
movsd (%rax), %xmm2
leaq 0(%rbp,%r12), %rax
movl $3, %edi
addq %rbx, %rax
salq $3, %rax
leaq -53792(%rcx,%rax), %rbx
leaq -26896(%rcx,%rax), %r8
leal -3(%r10), %eax
shrl %eax
imulq $26896, %rax, %rax
subq %rax, %rbx
.p2align 4,,10
.p2align 3
.L4:
movsd 13448(%r8), %xmm3
subq $26896, %r8
movslq %edi, %rax
movapd %xmm3, %xmm1
subsd %xmm2, %xmm1
movsd 26896(%r8), %xmm2
mulsd -16(%rdx,%rdi,8), %xmm1
addsd %xmm1, %xmm0
movapd %xmm2, %xmm1
subsd %xmm3, %xmm1
mulsd -8(%rdx,%rdi,8), %xmm1
addq $2, %rdi
cmpq %rbx, %r8
addsd %xmm1, %xmm0
jne .L4
.L3:
movq %r9, %rdi
movslq %r11d, %r11
addq %r12, %rbp
subq %rax, %rdi
imulq $1681, %rdi, %rdi
imulq $13448, %r11, %r11
imulq $-13448, %r9, %r8
addq %rdi, %rbp
leaq (%rcx,%rbp,8), %rcx
.p2align 4,,10
.p2align 3
.L5:
movsd (%rcx), %xmm1
leaq (%rcx,%r11), %rdi
subq $13448, %rcx
subsd (%rdi,%r8), %xmm1
mulsd (%rdx,%rax,8), %xmm1
addq $1, %rax
cmpl %eax, %r10d
addsd %xmm1, %xmm0
jge .L5
popq %rbx
.cfi_def_cfa_offset 24
popq %rbp
.cfi_def_cfa_offset 16
movsd %xmm0, (%rsi)
popq %r12
.cfi_def_cfa_offset 8
ret
.p2align 4,,10
.p2align 3
.L10:
.cfi_restore 3
.cfi_restore 6
.cfi_restore 12
rep ret
.p2align 4,,10
.p2align 3
.L6:
.cfi_def_cfa_offset 32
.cfi_offset 3, -32
.cfi_offset 6, -24
.cfi_offset 12, -16
movl $1, %eax
jmp .L3
.cfi_endproc
.LFE0:
.size frac_, .-frac_
.ident "GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0"
.section .note.GNU-stack,"",@progbits