我正在尝试将此汇编函数与此 C++ 代码链接:
.text
.global _Z7scambiaRiS_
_Z7scambiaRiS_:
pushq %rbp
mov %rsp, %rbp
mov (%rdi), %rax
mov (%rsi), %rcx
mov %rcx, (%rdi)
mov %rax, (%rsi)
leave
ret
.data
#include <iostream>
void extern scambia(int &a, int &b);
int main()
{
int a, b;
std::cin>>a>>b;
std::cout<<"a: "<<a<<" b: "<<b<<"\n";
scambia(a, b);
std::cout<<"a: "<<a<<" b: "<<b<<"\n";
return 0;
};
Assembly 是 intel x86-64 版本。
程序可以运行,但随后会因分段错误而停止, 这是输出,作为输入给出
3 4
:
3 4
a: 3 b: 4
a: 4 b: 3
*** stack smashing detected ***: terminated
Aborted (core dumped)
我真的不明白我是如何设法破坏堆栈的,甚至使用 gdb 进行调试我也无法找出出了什么问题
scambia
被声明为引用 int
,在此平台上为 4 个字节。 然而
mov (%rdi), %rax
mov (%rsi), %rcx
mov %rcx, (%rdi)
mov %rax, (%rsi)
正在执行 8 字节加载和存储,因为
rax
和 rcx
是 64 位寄存器。 因此,它们每个人都会在您传入的int
之外写入4个字节,这意味着其他堆栈空间被覆盖,从而触发堆栈粉碎检测器。
要按原样使用汇编函数,应在 C++ 中将其声明为引用
int64_t
或其他 64 位类型。 (long int
在许多平台上都是 64 位,但不是全部)。
要保持声明交换两个
int
,请更改汇编代码以使用 32 位寄存器来将数据移入和移出内存:
mov (%rdi), %eax
mov (%rsi), %ecx
mov %ecx, (%rdi)
mov %eax, (%rsi)
注意
rdi
和 rsi
应保持原样,因为它们是 64 位的指针。