c - 撤回非法指令

标签 c function assembly x86 nasm

我正在处理一个在 main.c 中调用的程序集中实现函数的项目。 C 中的签名函数声明是 void strrev(char *str) ; Ret 指令给我一个非法指令错误。为什么?这是我第一次这样做。

尝试只发布相关代码:

SECTION .text
        global strrev

strrev:
        push    ebp
        mov     ebp, esp

        push    esi
        push    edi
        push    ebx

// doing things with al, bl, ecx, edi, and esi registers here


// restore registers and return    
        mov     esp,    ebp
        pop     ebx
        pop     edi
        pop     esi
        pop     ebp

        ret

错误:

(gdb)
Program received signal SIGILL, Illegal instruction.
0xbffff49a in ?? ()

这样编译链接:

nasm -f elf -g strrepl.asm
nasm -f elf -g strrev.asm
gcc -Wall -g -c main7.c
gcc -Wall -g strrepl.o strrev.o main7.o

最佳答案

mov esp, ebpesp 更改为指向执行 mov ebp, esp 时的位置。那是在您将 esiediebx 压入堆栈之前,因此您无法再弹出它们。因为你这样做,堆栈是错误的,ret 没有按预期工作。

您可能会删除 mov esp, ebp 指令。仅当您在例程中对堆栈指针进行了可变更改(例如,将堆栈移动到所需的对齐方式或为可变长度数组腾出空间)时,才需要像这样恢复堆栈指针。如果您的堆栈处理简单,那么您只需按与推送内容相反的顺序弹出。如果你确实对堆栈进行了变量更改,那么你需要将指针恢复到不同的位置,而不是你保存的ebp,这样你就可以弹出ebxediesi

关于c - 撤回非法指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15977809/

相关文章:

assembly - 如何将寄存器中的VALUE移至NASM中的存储变量?

assembly - 80x86 16位asm : lea cx, [cx * 8 + cx]在NASM上导致错误(编译.com文件)

c函数返回数组并将数组与另一个数组进行比较

Python:递归函数的基本情况

c - 删除链表的唯一节点

c - C中退出代码11的含义?

function - 为什么没有类似于atan2()的asin2()和acos2()函数?

assembly - MOVZX缺少32位寄存器到64位寄存器

c - 希望 execve() 运行的可执行文件使用我预加载的库

c - 为什么 "static"被忽略?