gpt4 book ai didi

c - 带有内联汇编段错误的程序,除非以函数调用为前缀

转载 作者:行者123 更新时间:2023-11-30 15:41:10 25 4
gpt4 key购买 nike

#include <stdio.h>

static void my_func(char *text) {
//printf("hello again\n");
__asm__(
"push %%ebp\n\t"
"mov %0, %%ebx\n\t"
"push %%ebx\n\t"
"call strlen\n\t"
"movb (%%ebx), %%al"
: : "r"(text));
}

int main() {
int i;
for(i = 0; i < 3; ++i)
my_func("hello");
}

测试运行:

$ gcc -v
(...)
gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)
$ gcc test.c
$ ./a.out
Segmentation fault (core dumped)

为什么我的程序会崩溃,除非我取消注释 printf 调用?

这是两个函数的反汇编:

OK 版本(带 printf 调用):

0804844d <my_func>:
804844d: 55 push %ebp
804844e: 89 e5 mov %esp,%ebp
8048450: 83 ec 18 sub $0x18,%esp
8048453: c7 04 24 30 85 04 08 movl $0x8048530,(%esp)
804845a: e8 b1 fe ff ff call 8048310 <puts@plt>
804845f: 8b 45 08 mov 0x8(%ebp),%eax
8048462: 89 c3 mov %eax,%ebx
8048464: 53 push %ebx
8048465: e8 c6 fe ff ff call 8048330 <strlen@plt>
804846a: 8a 03 mov (%ebx),%al
804846c: c9 leave
804846d: c3 ret

崩溃版本(没有 printf 调用):

 0804841d <my_func>:
804841d: 55 push %ebp
804841e: 89 e5 mov %esp,%ebp
8048420: 8b 45 08 mov 0x8(%ebp),%eax
8048423: 89 c3 mov %eax,%ebx
8048425: 53 push %ebx
8048426: e8 d5 fe ff ff call 8048300 <strlen@plt>
804842b: 8a 03 mov (%ebx),%al
804842d: 5d pop %ebp
804842e: c3 ret

最佳答案

"push %%ebx\n\t"
"call strlen\n\t"

PUSH堆栈上的某些内容。您希望谁POP从堆栈中删除某些内容(清理您的调用参数)?

Linux 使用“caller cleanup ”调用约定,并且通过不清理调用堆栈,您会使 my_func 返回到虚假地址(这会导致 SIGSEGV) .

关于c - 带有内联汇编段错误的程序,除非以函数调用为前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20603546/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com