【问题标题】:String copy in Assembly汇编中的字符串复制
【发布时间】:2014-11-25 20:40:33
【问题描述】:

我在将字符串复制到 Assembly 中的空数组时遇到问题。

首先,我得到了一些我想复制的垃圾而不是字符串。

其次,程序应该使用最多 100 个字符的字符串,但是当我声明一个包含 100 个字符的数组时,我得到“*** 检测到堆栈粉碎 ***" 使用 gcc 编译后。

#include<stdio.h>
void main() {
    char *s="aac";
    char t[4];
    asm volatile ( 
        ".intel_syntax noprefix;" 
        "mov eax, %0;"
        "push eax;" 
        "mov eax, %1;"
        "push eax;" 
        "call printing;"
        "jmp end;"
        "printing:"
        "push ebp;" 
        "mov ebp,esp;" 
        "push eax;"
        "push ebx;" 
        "push ecx;"
        "push edx;" 

        "mov ebx,[ebp+12];"
        "mov eax,[ebp+8];"

        "mov ecx,eax;"

        "copying:"
        "mov dl,[ebx];"
        "mov [eax],dl;"
        "inc ebx;"
        "inc eax;"
        "cmp dl,0;"
        "jnz copying;"

        "xor edx,edx;"

        "mov eax,4;"
        "mov ebx,1;"

        "mov edx,3;"
        "int 0x80;"
        "pop edx;"
        "pop ecx;"
        "pop ebx;"
        "pop eax;"
        "pop ebp;"
        "ret 4;"

        "end:"

        ".att_syntax prefix;"
    :
    :"r" (s), "r" (t)
    :"eax"
    );

printf("\n");

}

我是大会的新手,所以请帮助我。

提前谢谢你

【问题讨论】:

    标签: c assembly intel-syntax


    【解决方案1】:

    我发现您的代码存在四个问题:

    • 您正在使用寄存器al 作为传输字符的缓冲区,同时您正在使用eax 作为源指针。 al 只是eax 的最低八位的名称,因此您正在破坏源指针。您可能想改用edx。破坏源指针会导致不确定的复制长度,并且可能会溢出堆栈上的目标缓冲区,这将导致堆栈粉碎错误。
    • 堆栈上的目标缓冲区太小。您正在尝试复制 3 个字符和 NUL 字节,这需要目标缓冲区中的四个字节。
    • 您将在循环之后将eax 的值传递给write 系统调用。这指向复制目标,因为您在循环期间增加了eax。如果您在复制循环之前将eax 复制到ecx,则该问题已得到解决。
    • 最后,您复制了三个非 NUL 字符,但只打印了两个。

    【讨论】:

    • 对不起,我完全不明白。你能展示我应该更改的代码片段吗?
    • 另一个答案已经解决了第一点,所以你根本不需要对那个做任何事情。第二点是针对您的示例中的 t 声明。第三点是关于“mov ecx,eax”指令的位置,最后一点是关于传递给write linux系统调用的count参数(作为它的第三个参数,它在edx中传递)
    • 好的。我认为我用你的建议纠正了它并且它有效。非常感谢。但我仍然有声明:“***堆栈粉碎检测到***”。为什么?
    • 糟糕,我似乎错过了您代码中的另一个错误。 return 指令后面的数字包含要从堆栈中删除的参数的字节数。您正在推送 2 个 32 位的值(源指针和目标指针),因此总共 8 个字节。因此,您需要将 ret 4 更改为 ret 8。
    • 好的,它有效。 :) 这取决于我使用了多少变量并将其推入堆栈?
    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 2021-06-13
    • 1970-01-01
    • 2019-10-11
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    相关资源
    最近更新 更多