brk 45

下面的结论是调试中得出的,没有看kenel代码。。。可能有问题、欢迎指正、谢谢

 

<code>

.section .data

brk_addr_fmt: .ascii "brk address is %p/n"

.section .bss

.section .text

 

.type _start, @function

.globl _start

.type mybrk, @function

_start:

movl %esp, %ebp

 

pushl $0

call _mybrk

addl $4, %esp

 

pushl %eax

pushl $brk_addr_fmt

call printf

addl $4, %esp

popl %eax

 

 

# 虽然这里只申请了 8 个字节,参后

addl $8, %eax

pushl %eax

call _mybrk

addl $4, %esp

 

# 虽然前面只申请了 8 个字节,但是 1(%eax) 不会越界的

# 这是因此本次是第一次 brk kernel 发现只申请 8 个,

# 但实际会申请 4096(0x1000) 个字节的内存

# 因此即使 movl $1, FFC(%eax) 也不会出错

# 但是如果 movl $1, FFD(%eax) 就会出现 segemntation fault

movl $1, 1(%eax)

 

pushl %eax

pushl $brk_addr_fmt

call printf

addl $8, %ebp

 

 

pushl $0

call _mybrk

addl $4, %esp

 

pushl %eax

pushl $brk_addr_fmt

call printf

addl $8, %ebp

 

_exit:

movl $1, %eax

movl $0, %ebx

int $0x80

 

 

_mybrk:

pushl %ebp

movl %esp, %ebp

 

movl $45, %eax

movl 8(%ebp), %ebx

int $0x80

 

movl %ebp, %esp

popl %ebp

ret

 

</code>

 

break到底是什么,break就是一个地址,该地址是从.text到stack方向、i.e. 从低地址到高地址方向中,第一个尚未map的内存单元,或者说成下一次map逻辑地址到物理地址时、会被map的第一个内存单元更合适

statck 是向下生长的,通过brk(45) map内存时,是向上推动break边界的,如下面的逻辑地址图所示,该图表示尚未进行过brk时,系统的逻辑地址示意图,其中...表示内容,xxx表 示尚未map的逻辑地址,???表示已经map、但是尚未使用的逻辑地址
|  stack_bottom | 0xBFFF FFFF
|  ...          |
|  ...          |
|  stack_top    |
|  xxx          |
|  xxx          |
|  xxx          |
|  xxx          |
|  xxx          |
|  xxx          |
|  xxx          |
|  xxx          |
|  xxx          | break
|  ...          |
|  ...          |
|  ...          |
|  ...          | .section
|  ...          |
|  ...          | 0x0804 8000
现在进行提高break边界的操作,i.e. 请求kernel将部分虚拟内存map到物理内存
movl $45,  %eax; movl $0, %ebx; int  $0x80
movl %eax, %ebx; addl $8, %ebx; movl $45, %eax; int 0x80;
该图会变为如下,i.e. brk后kernel会分配页的整数倍的空间,x86的页大小是4096,上面三条指令执行后,break的地址会变成break+0x8
|  stack_bottom | 0xBFFF FFFF
|  ...          |
|  ...          |
|  stack_top    |
|  xxx          |
|  xxx          |
|  xxx          |
|  xxx          | break+0x1000
|  ???          |
|  ???          |
|  ...          | break'= break + 0x8
|  ...          |
|  ...          | break
|  ...          |
|  ...          |
|  ...          |
|  ...          | .section
|  ...          |
|  ...          | 0x0804 8000

注意:以上的讨论是第一次进行brk时的情况,如果多次进行brk,不一定是上图所示,例如连续两次brk,第二次brk时,kernel就不会进行map
movl $45,  %eax; movl $0, %ebx; int  $0x80
movl %eax, %ebx; addl $8, %ebx; movl $45, %eax; int 0x80;
movl %eax, %ebx; addl $8, %ebx; movl $45, %eax; int 0x80;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章