为什么我会收到“** stack crashing detector **”错误?

问题描述 投票:0回答:1

我正在尝试将此汇编函数与此 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 进行调试我也无法找出出了什么问题

c++ assembly x86-64
1个回答
0
投票

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 位的指针。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.