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;

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