我在每个网页上搜索答案,但我似乎无法找到答案。我已经学习了大约2个月的网络汇编语法,我正在尝试找到一种在内存中存储数据的方法。
我知道sys_break:
mov,eax 45
保留内存,我有一个保留16kb内存的功能宏:
%macro reserve_mem
mov eax,45
xor ebx,ebx
int 80h
add eax,16384
mov ebx,eax
mov eax,45
int 80h
%endmacro
我也知道当你保留字节(resb),单词等。在.bss部分中,内存的一小部分被分配给未初始化的数据。
此外,还有虚拟内存,可以使用0x0000这样的地址访问,然后将其映射到实际的内存位置。
然而,我的问题是我试图将数据存储在内存中,但我尝试的所有内容都以分段错误(核心转储)结束,这是试图访问它无权访问的内存的程序。我尝试过如下代码。
mov [0x0000],eax
谢谢你的帮助。
答案 0 :(得分:1)
你似乎误解了虚拟内存的概念。它类似于电话号码,因为你不能在每个10位数的组合上打电话给某人。您只需拨打电话簿中列出的号码即可拨打电话。否则你会听到"抱歉,这个号码目前无法使用"。同样,只有每个进程的页表中列出的那些虚拟地址(始终由OS自动和透明地维护)对于访问进程是有效的。 SEGV是操作系统的说法"抱歉,这个虚拟地址目前无法使用。"
在您的代码中,您取消引用0x0000
,但它是虚拟虚拟地址的最不可能的值之一。您最终这样做是因为您丢弃了brk(2)
系统调用返回的有效虚拟地址(仔细阅读man 2 brk
,因为原始系统调用从glibc brk
和{{ 1}}。)您的代码将以这种方式转换为C(尽管如今glibc sbrk
通常依赖于malloc(3)
而不是mmap(2)
):
brk(2)
这显然是错误的,你必须做这样的事情:
void *p = malloc(16384);
int eax = ...;
(void *)0 = eax;
应该转换为这样的NASM:
void *p = malloc(16384);
int *p0 = (int *)p + 0;
int *p1 = (int *)p + 1;
int eax = ...;
int ebx = ...; /* it's all up to you which register to use */
*p0 = eax;
*p1 = ebx;
我对汇编编程的了解很严重,上面的代码可能包含很多错误......但概念部分不应该是错误的。