cra*_*dr4 5 linux x86 assembly nasm segmentation-fault
出于好奇,我正在学习x86程序集.我目前正在使用基于Linux的操作系统和NASM汇编程序.我很难理解为什么
SECTION .text
global _start
_start:
nop
mov ebx, 25
mov [0xFFF], ebx
;Exit the program
mov eax, 1
mov ebx, 0
int 0x80
Run Code Online (Sandbox Code Playgroud)
会导致分段错误(将ebx寄存器的内容移动到内存位置0xFFF时).我认为在纯asm中构建程序会让我无限制地访问我的进程的虚拟地址空间.这不是这种情况吗?
你会如何在汇编中实现类似堆的东西?
在Linux(x86)上 - 虽然您的进程中的虚拟地址范围为4gb,但并非所有地址都可访问.上部1gb是内核所在的位置,并且存在无法使用的低内存区域.无法写入或读取虚拟内存地址0xfff(默认情况下),因此程序崩溃时会出现段错误.
在后续注释中,您建议您打算在汇编程序中创建堆.这可以做到,一种方法是使用sys_brk系统调用.它通过int 0x80和EAX = 45 访问.它在EBX中使用一个指针代表堆的新顶部.通常,堆区域的底部初始化为程序数据段之外的区域(在内存中的程序之上).要获取初始堆位置的地址,可以在EBX设置为0的情况下调用sys_break.在系统调用之后,EAX将成为堆的当前基本指针.当您需要访问堆内存或分配更多堆空间时,可以将其保存.
此代码提供了一个示例,用于清晰(不是性能),但可能是了解如何操作堆区域的起点:
SECTION .data
heap_base: dd 0 ; Memory address for base of our heap
SECTION .text
global _start
_start:
; Use `brk` syscall to get current memory address
; For the bottom of our heap This can be achieved
; by calling brk with an address (EBX) of 0
mov eax, 45 ; brk system call
xor ebx, ebx ; don't request additional space, we just want to
; get the memory address for the base of our processes heap area.
int 0x80
mov [heap_base], eax ; Save the heap base
;Now allocate some space (8192 bytes)
mov eax, 45 ; brk system call
mov ebx, [heap_base] ; ebx = address for base of heap
add ebx, 0x2000 ; increase heap by 8192 bytes
int 0x80
; Example usage
mov eax, [heap_base] ; Get pointer to the heap's base
mov dword [eax+0xFFF], 25 ; mov value 25 to DWORD at heapbase+0xFFF
;Exit the program
mov eax, 1
xor ebx, ebx
int 0x80
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
595 次 |
| 最近记录: |