我目前正在学习如何将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之前;嗨"是指向存储字符串的内存的只读部分?我正在自学这个,所以我很感激澄清。
答案 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