因此,我正在學習使用NASM語法的x86 Linux程序集(哦,上帝,而不是這個,你們都在想)。我正在嘗試創建一個子例程,它將簡單地將EAX中的值打印到標準輸出。代碼運行並退出,沒有錯誤,但沒有打印。我無法弄清楚爲什麼。首先,這裏是我的工作文件:Linux x86 NASM - 子程序:從EAX打印一個dword
segment .bss
to_print: resd 1
segment .text
global print_eax_val
print_eax_val: ; (top)
push dword ebx ;Stack: edx
push dword ecx ; ecx
push dword edx ; ebx
; (bot)
mov ecx,eax ;ecx = eax
mov [to_print],ecx ;to_print = ecx
mov eax, 4 ;sys_write
mov ebx, 1 ;to stdout
add ecx, 47 ;add 47 for ASCII numbers
mov edx, 2 ;double word = 2 bytes
int 0x80
mov eax, [to_print] ;eax = original val
pop edx ;pop the registers back from the stack
pop ecx
pop ebx ;Stack: empty
ret
這是從我的主文件,它看起來像這樣所謂的(這可能是無關緊要的,除非我失去了一些激烈的)。
segment .data
hello db "Hello world!", 0
newline db 0xA
len equ $ - hello
len2 equ $ - newline
segment .text
extern print_nl
extern print_eax_val
global main
main:
enter 0,0
call print_nl
mov eax, 1
call print_eax_val
mov ebx, 0 ;exit code = 0 (normal)
mov eax, 1 ;exit command
int 0x80 ;ask kernel to quit
print_nl
只是定義和打印換行符的另一個子例程。這將成功運行並按預期打印新行。
問題是否與我的sys_write
調用的長度參數有關?我給它2,這是dword
的大小,這是EAX
登記冊和我的to_print
標籤的大小,我用resd 1
保留了這個標籤。我試圖改變長度到1,4,8,16,和32絕望......沒有任何工作。
編輯:的人誰不知道,這裏是我固定的代碼:(我將把星號上,我改變行):
segment .bss
to_print: resd 1
segment .text
global print_eax_val
print_eax_val: ; (top)
push dword ebx ;Stack: edx
push dword ecx ; ecx
push dword edx ; ebx
; (bot)
mov ecx,eax ;ecx = eax
mov [to_print],ecx ;to_print = ecx
**** add dword [to_print], 48
mov eax, 4 ;sys_write
mov ebx, 1 ;to stdout
**** mov ecx, to_print
mov edx, 2
int 0x80
**** sub dword [to_print], 48
mov eax, [to_print] ;eax = original val
pop edx ;pop the registers back from the stack
pop ecx
pop ebx ;Stack: empty
ret
基本上,ecx
必須包含地址你想要打印的塊的大小,而不是值本身。正如在選定的答案中指出的那樣,如果eax在0-9範圍內,這將僅工作。
編輯2:所以我對sys_write的第二個參數(存儲在edx
中的第二個參數)有點困惑。我認爲它只是指一些字節。因此,對於dword
,正如我使用的那樣,在那裏使用4是合適的,因爲雙字是4字節或32位。我猜測它是有效的,因爲x86是小端。因此,在內存,to_print
十六進制值應該是這樣的:
90 00 00 00
而且隨着兩個提供長度,SYS_WRITE得到:
90 00
所以價值幸運的是沒有被損壞。
後來我改變了代碼存儲to_print
作爲一個字節,而不是使用resb 1
使用byte
代替dword
訪問它...字節是在這裏很好,因爲我知道我不會給to_print
以上的值9.
非常感謝!你的回答非常有幫助。是的,我意識到這隻會在0到9之間工作,我只是試圖弄清楚一些基礎知識。也許我會最終開始一些數組/指針int到字符串的業務。我將使用更新的代碼編輯我的帖子,供任何想知道的人使用。 –
我讚賞你處理彙編語言,並祝你好運。順便說一句,你的問題是一個典型的好SO問題。您準確地提供了所需的信息,顯示了您所嘗試的內容,並提出了具體問題。 +1 –
再次感謝,我一定會將您的答案歸類爲「原型好的SO」答案。在我正在開發的一個項目中,我決定在一個巨大的C++ segfault/pointer崩潰之後學習一些x86程序集。首先,這是一個很好的轉換,其次,我想知道我在編寫代碼時實際做了什麼。 –