由网友(眉间上的悲痛)分享简介:C代码:void PtrArg1(int* a,int* b,int* c, int* d, int* e, int* f){return;}void PtrArg2(int* a,int* b,int* c, int* d, int* e, int* f, int* g, int* h){return;}使用...![分别用字符数组和字符指针作函数参数两种方法编程实现在字符串中删除与某字符相同的字符](https://p.xsw88.cn/allimgs/daicuo/20230903/2604.png)
C代码:
void PtrArg1(int* a,int* b,int* c, int* d, int* e, int* f)
{
return;
}
void PtrArg2(int* a,int* b,int* c, int* d, int* e, int* f, int* g, int* h)
{
return;
}
使用
编译gcc -c -m64 -o basics basics.c -O0
![分别用字符数组和字符指针作函数参数两种方法编程实现在字符串中删除与某字符相同的字符](https://p.xsw88.cn/allimgs/daicuo/20230903/2604.png)
正在运行
objdump -d basics -M intel -r
然后导致以下反汇编(英特尔语法):
000000000000000b <PtrArg1>:
b: f3 0f 1e fa endbr64
f: 55 push rbp
10: 48 89 e5 mov rbp,rsp
13: 48 89 7d f8 mov QWORD PTR [rbp-0x8],rdi
17: 48 89 75 f0 mov QWORD PTR [rbp-0x10],rsi
1b: 48 89 55 e8 mov QWORD PTR [rbp-0x18],rdx
1f: 48 89 4d e0 mov QWORD PTR [rbp-0x20],rcx
23: 4c 89 45 d8 mov QWORD PTR [rbp-0x28],r8
27: 4c 89 4d d0 mov QWORD PTR [rbp-0x30],r9
2b: 90 nop
2c: 5d pop rbp
2d: c3 ret
000000000000002e <PtrArg2>:
2e: f3 0f 1e fa endbr64
32: 55 push rbp
33: 48 89 e5 mov rbp,rsp
36: 48 89 7d f8 mov QWORD PTR [rbp-0x8],rdi
3a: 48 89 75 f0 mov QWORD PTR [rbp-0x10],rsi
3e: 48 89 55 e8 mov QWORD PTR [rbp-0x18],rdx
42: 48 89 4d e0 mov QWORD PTR [rbp-0x20],rcx
46: 4c 89 45 d8 mov QWORD PTR [rbp-0x28],r8
4a: 4c 89 4d d0 mov QWORD PTR [rbp-0x30],r9
4e: 90 nop
4f: 5d pop rbp
50: c3 ret
PtrArg1
和PtrArg2
的参数数量不同,但两者的汇编指令是相同的。为什么?
推荐答案
这是由于调用约定(system V AMD64ABI,current version 1.0)。前六个参数在整数寄存器中传递,其他所有参数都被压入堆栈。
执行Until LocationPtrArg2+0x4e
后,您会得到以下堆栈布局:
+----------+-----------------+
| offset | content |
+----------+-----------------+
| rbp-0x30 | f |
| rbp-0x28 | e |
| rbp-0x20 | d |
| rbp-0x18 | c |
| rbp-0x10 | b |
| rbp-0x8 | a |
| rbp+0x0 | saved rbp value |
| rbp+0x8 | return address |
| rbp+0x10 | g |
| rbp+0x18 | h |
+----------+-----------------+
因为g
和h
是由调用方推送的,所以两个函数得到相同的反汇编。对于呼叫者
void Caller()
{
PtrArg2(1, 2, 3, 4, 5, 6, 7, 8);
}
(为清楚起见,我省略了必要的强制转换)我们将得到以下反汇编:
Caller():
push rbp
mov rbp, rsp
push 8
push 7
mov r9d, 6
mov r8d, 5
mov ecx, 4
mov edx, 3
mov esi, 2
mov edi, 1
call PtrArg2
add rsp, 16
nop
leave
ret
(see compiler explorer)
参数h = 8
和g = 7
在调用PtrArg2
之前被推送到堆栈上。
相关推荐
最新文章