先看一下以下的程序码,以及用他来编译出来的组合语言
// add.c
#include <stdio.h>
long add(long a, long b)
{
return a + b;
}
int main()
{
int a, b, c;
a = -1;
b = -2;
c = add(a, b);
printf("%d\n", c);
return 0;
}
在终端机输入:
$ gcc -Og -S add.c #产生组合语言
虽然产生出来的组合语言看起来很杂乱,但等等只要看看重点的几行就好
1 .file "add.c"
2 .text
3 .globl add
4 .type add, @function
5 add:
6 .LFB11:
7 .cfi_startproc
8 leaq (%rdi,%rsi), %rax
9 ret
10 .cfi_endproc
11 .LFE11:
12 .size add, .-add
13 .section .rodata.str1.1,"aMS",@progbits,1
14 .LC0:
15 .string "%d\n"
16 .text
17 .globl main
18 .type main, @function
19 main:
20 .LFB12:
21 .cfi_startproc
22 subq $8, %rsp
23 .cfi_def_cfa_offset 16
24 movq $-2, %rsi
25 movq $-1, %rdi
26 call add
27 movq %rax, %rsi
28 leaq .LC0(%rip), %rdi
29 movl $0, %eax
30 call printf@PLT
31 movl $0, %eax
32 addq $8, %rsp
33 .cfi_def_cfa_offset 8
34 ret
35 .cfi_endproc
36 .LFE12:
37 .size main, .-main
38 .ident "GCC: (Debian 10.2.1-6) 10.2.1 20210110"
39 .section .note.GNU-stack,"",@progbits
重点的几行:
5 add:
...
8 leaq (%rdi,%rsi), %rax # a + b
9 ret
19 main:
...
24 movq $-2, %rsi # b = -2
25 movq $-1, %rdi # a = -1
26 call add # add(a, b)
...
从这几行可以看到c语言中的function call在组合语言中是如何被实作的:
1.先把-1丢进%rdi
、-2丢进%rsi
(24,25行)
2.call add
(26行)
3.add
执行%rdi
* rsi
的动作,并把内容放到%rax
中
4.从add
return回main
add
这个subroutine之所以拿%rdi
跟%rsi
这两个暂存器来做相乘,是因为他相信第一个跟第二个参数分别被放在%rdi
跟%rsi
中
而这种信任的合作模式,通常书上会使用convention(习俗、习惯)来称呼
我的疑问:
既然这是习俗,应该代表并不是强制上必须要这麽做的吧?
习惯上用%rdi及%rsi来当第1第2个参数,但用其他的暂存器(如%r8,%r9)应该也可以吧?
所以来做个小小的实验,来修改gcc产生出来的add.s
档:
5 add:
...
8 leaq (%r8,%r9), %rax # a + b (改成r8乘r9)
9 ret
19 main:
...
24 movq $-2, %r8 # b = -2 (从%rsi改成%r9)
25 movq $-1, %r9 # a = -1 (从%rdi改成%r8)
26 call add # add(a, b)
...
# 编译修改後的add.s
$ gcc -c add.s -Og
$ gcc -o add add.o -Og
执行:
$ ./add
-3
可以看到就算使用了其他的暂存器,也一样是可以的,gcc也没有给出任何的警告或错误
<<: [WMX3] 7.IO - Set/Get OutBytes
PHP的资料型态 Array数组 PHP中的array 实际上是一个有序映射。映射是一种把 valu...
前言 这篇跟工程师其实没那麽有关,适合给新手leader定OKRs的时候看看。 演讲总结 今天要讲...
Youtube 频道:https://www.youtube.com/c/kaochenlong ...
Hello 大家, 不知不觉来到连假的最後一天了, 要开始收心罗~ 是不是有一些朋友又请了三天特休来...
关於 Hook 的方法与实作 useState useState 是 hook 的函数,它接收的参数...