2014-08-27 26 views
-1

我有搜索每個網頁的答案,但我似乎無法找到它。我一直在學習大約2個月的全網程序集語法,並且我試圖找到一種將數據存儲在內存中的方法。如何在Assembly(NASM)中不使用變量的情況下將數據存儲在內存中?

我知道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

爲什麼0x0000?你只能訪問已經分配給你的進程的內存,或者靜態地用'resb'等,或者動態地用例如。 'sys_brk'。 – Michael 2014-08-27 12:02:23

+0

感謝您的回覆,但是可以這樣做,比如將數字1放入內存中? – morgan 2014-08-27 12:07:10

+0

@morgan至少x86支持這樣的操作。你是否熟悉C或其他編程語言?你在計算機編程領域有什麼樣的經驗?我們需要知道你的水平,才能向你提供有效的建議。 – nodakai 2014-08-27 12:21:39

回答

1

你似乎誤解了虛擬內存的概念。這與電話號碼相似,因爲您無法在每個約有10位數的組合中撥打電話。只有通過電話簿中列出的號碼才能打電話給你。否則,您會聽到「對不起,此號碼目前無法使用」。同樣,只有那些在每個進程的頁表中列出的虛擬地址(通常由OS自動且透明地維護)才能被進程訪問。 SEGV是操作系統的一種說法,「對不起,這個虛擬地址目前沒有服務。」

在您的代碼中,您取消了引用0x0000,但它是虛擬地址最不可能的值之一。你最終這樣做是因爲你扔掉了brk(2)系統調用返回的有效虛擬地址(仔細閱讀man 2 brk,因爲原始系統調用的行爲不同於glibc brksbrk)。您的代碼將以這種方式轉換爲C(儘管時下的glibc malloc(3)往往依賴於mmap(2)而非brk(2)):

void *p = malloc(16384); 
int eax = ...; 
(void *)0 = eax; 

這顯然是錯誤的,你必須做這樣的事情:

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; 

該笑ULD轉化爲NASM是這樣的:

reserve_mem ; IIRC eax now points to the last 
mov ecx, eax ; byte of the newly allocated chunk 
sub ecx, 16383 ; set p0 (== p) 
mov edx, ecx 
add edx, 4 ; set p1; 4 is for sizeof(int) 
; ... set whatever value to eax ... 
; ... set whatever value to ebx ... 
mov [ecx], eax ; *p0 = eax; 
mov [edx], ebx ; *p1 = ebx; 

我對彙編語言編程知識是生鏽和上面的代碼可能包含很多錯誤......但這個概念的部分不應該有太多的錯誤。

+0

謝謝,你和邁克爾已經擴展了我的知識,以便我可以開始嘗試開發更復雜的程序。 – morgan 2014-08-27 23:04:52

相關問題