从程序集中访问C指针

时间:2015-07-09 03:21:28

标签: c pointers assembly

我目前正在学习如何将C代码与汇编混用。在.c文件中,我有以下代码:

extern int replace(char *c);
int main(){
  static char * string2 = "aaab\n";
  static char * string3;
  string3 = (char *) replace(string2);
  *string3 = 'A';
  printf("%s",string3);
}

汇编函数replace具有以下代码:

section .data
string db "Test",10,0
section .text
global replace
replace: 
enter 0,0
mov eax, string
leave 
ret

这非常有效并且表明C程序可以访问.asm文件内存。但是当我尝试写入指针string2时,比如将以下代码添加到函数replace中,

mov edx, [ebp + 8]
mov byte [edx], 10

我获得了分段错误。 (根据我的理解,后者将指针的地址传递给edx,因此edx = string2,然后通过* edx = 10分配* string2 = 10)。你能解释一下我做错了什么吗?

编辑:我发现当我做一个string3 =(char *)malloc(10); 然后我确实可以在汇编中做到

mov edx, [ebp + 8]
move byte [edx], 10

并获得正确的结果。我仍然很感激解释为什么会这样。这是由于堆可公开访问吗?这可能是因为在char * string =&#34之前;嗨"是指向存储字符串的内存的只读部分?我正在自学这个,所以我很感激澄清。

1 个答案:

答案 0 :(得分:2)

您的C程序中的问题是由于创建了一个无法修改的字符串文字:

static char *string2 = "aaab\n";

您可以通过替换呼叫为string3分配指针string2

string3 = (char *) replace(string2);

然后,您可以尝试修改只读内存(string2),方法是将a中的第一个字符更改为A

*string3 = 'A';

导致段错误。要修复段错误,只需将string2声明更改为:

static char string2[] = "aaab\n";

因此它只是一个字符数组而不是字符串文字。

使用char *label = "stuff";创建文字时,可以在只读内存中创建文字。您可以通过使用gcc -S -masm=intel -o file.asm file.c转储C程序的程序集来轻松地看到这一点。如果你看,你会看到在"aaab\n"(只读)数据部分创建了.rodata

    .section        .rodata
    .string "aaab\n"
    .data
    .align 8