2015-01-14 92 views
0

我想讀取用戶的3個數字,我把它們存儲在一個數組,然後我告訴他們在NASM使用保羅·卡特功能這裏是我的代碼:打印整數NASM

%include "asm_io.inc" 

SECTION .bss 

tab resb 3 

SECTION .data 
msg db "Un nombre :",10 

SECTION .text 
global main 
     main: 
    mov esi,tab 
    xor ecx,ecx 
get_data: 
    mov eax,msg 
    call print_string 
    call read_int 
    mov [esi+ecx],eax 
    inc ecx 
    cmp ecx,3 
    jne get_data 
    call print_nl 
    xor ecx,ecx 
    mov edi,tab 
print_data: 
    mov eax,[edi+ecx] 
    call print_int 
    inc ecx 
    cmp ecx,3 
    jne print_data 






    mov eax,1 ; exit code 
    int 0x80 ; call exit 

的問題是即不執行print_data循環並退出。

+0

你只保留3個字節'tab'。如果你想要3個dword,你應該使用'resd 3'而不是'resb 3',並且你應該在每次迭代結束時將ecx增加4而不是1。另外,我沒有介紹'asm_io.inc'中的函數是如何實現的,但'ecx'通常是一個_caller-saved_寄存器,這意味着您不應該依賴它來保持函數調用的值。你的'msg'字符串也似乎缺少一個NUL終止字節。 – Michael

+0

我已經修改了程序,正如你所說的那樣,期望'ecx'寄存器不被這些函數使用,但它仍然跳過該循環。 –

+0

它不能跳過循環。但也許它不會打印你想看到的結果。順便說一下,讀取asm代碼非常困難,沒有來自編寫它的人的評論。當你在代碼中添加更改時,更新你問題中的代碼。除此之外,你需要描述你所調用的功能實際上是做什麼的。 – Blechdose

回答

0

只是要清楚。這些變化是你做的嗎?即使ECX寄存器不被用作特定功能的輸入或輸出,它仍可能在內部使用。這就是邁克爾的意思與「ECX通常是來電者保存的」

%include "asm_io.inc" 

SECTION .bss 

tab resd 3 

SECTION .data 
msg db "Un nombre :",10,0 

SECTION .text 
global main 
main: 
mov edi,tab 
xor ecx,ecx 
get_data: 
push ecx 
mov eax,msg 
call print_string 
call read_int 
mov [edi+ecx*4],eax 
pop ecx 
inc ecx 
cmp ecx,3 
jne get_data 
call print_nl 
mov esi,tab 
xor ecx,ecx 
print_data: 
push ecx 
mov eax,[esi+ecx*4] 
call print_int 
pop ecx 
inc ecx 
cmp ecx,3 
jne print_data 

mov eax,1 ; exit code 
int 0x80 ; call exit 
+0

我已經完成了所有這些修改,並試圖推動所有寄存器,即使那些女巫沒有在循環中使用,但我仍然有同樣的問題n,順便說一下,如果你看看保羅卡特文檔(他書),你會發現他在調用函數之前不會推送任何寄存器。 –

+0

段寄存器設置是否正確? **書中說「本文中的早期程序都將從圖1.6中的簡單C驅動程序開始,它只是調用另一個名爲asm main的函數,這實際上是一個用匯編語言編寫的例程,首先,這可以讓C系統設置程序在保護模式下正確運行,所有段和它們對應的段寄存器將由C初始化。 – Fifoernik