2012-10-25 56 views
1

我正在嘗試編寫一個程序,允許我打印多個字符(字符串或整數)。我遇到的問題是我的代碼只打印其中一個字符,然後換行並停留在無限循環中。這是我的代碼:linux nasm打印多個字符

SECTION .data 
len EQU 32 
SECTION .bss 
num resb len 
output resb len 

SECTION .text 
GLOBAL _start 
_start: 
Read: 
    mov eax, 3 
    mov ebx, 1 
    mov ecx, num 
    mov edx, len 
    int 80h 

Point: 
    mov ecx, num 

Print: 
    mov al, [ecx] 
    inc ecx 
    mov [output], al 

    mov eax, 4 
    mov ebx, 1 
    mov ecx, output 
    mov edx, len 
    int 80h 

    cmp al, 0 
    jz Exit 

Clear: 
    mov eax, 0 
    mov [output], eax 
    jmp Print 

Exit: 
    mov eax, 1 
    mov ebx, 0 
    int 80h 

有人能指出我做錯了什麼嗎?

感謝,

Rileyh

回答

2

在你進入Print節首次ecx指向字符串的開始和你用它來單個字符複製到輸出字符串的開始。但是還有更多的指令,你用指向輸出字符串的指針覆蓋ecx,並且永遠不會恢復它,因此你永遠不會複製和打印剩餘的字符串。

此外,爲什麼要用單個字符串打電話給write(),目的是循環打印整個字符串?爲什麼不直接通過num而不是將單個字符複製到output並傳遞該字符?

+0

此外,從'read'系統調用的返回值應該被用來確定有多少字節已實際投入的緩衝區。 – Jester

+0

感謝堆。很好的答案。 – Progrmr

1

在上一個問題中,您將message顯示爲零終止的字符串,因此cmp al, 0將指示字符串的結尾。 sys_read不會創建以零結尾的字符串! (如果我們需要它,我們可以填入一個零 - 例如,作爲sys_open的文件名),sys_read將讀取最多的edx字符。當stdin返回sys_read時,只有當「enter」鍵被擊中時纔會返回。如果輸入的edx字符少於此字符串,則以換行字符(十進制10或十六進制0xA或0Ah)結束 - 您可以查找該字符......但是,如果討厭的用戶輸入的不是edx字符,只有edx字符會去進入你的緩衝區,「超額」保留在操作系統的緩衝區中(以後會引起麻煩!)。在這種情況下,您的字符串不會以換行符終止,因此查找它將失敗。 sys_read返回eax中實際讀取的字符數 - edx - 包括換行符 - 。如果你不想在長度中包含換行,你可以減少eax。

作爲一個實驗,在edx中用一些小數字(比如說4)做一個sys_read,然後退出程序。輸入「abcdls」(輸入)並觀察執行的「ls」。如果一些小丑打了「abcdrm -rf」......好吧,別!

最安全的事情是刷新操作系統的輸入緩衝區。

mov ecx, num 
    mov edx, len 
    mov ebx, 1 
    mov eax, 3 
    int 80h 
    cmp byte [ecx + eax - 1], 10 ; got linefeed? 
    push eax ; save read length - doesn't alter flags 
    je good 
flush: 
    mov ecx, dummy_buf 
    mov edx, 1 
    mov ebx, 1 
    mov eax, 3 
    int 80h 
    cmp byte [ecx], 10 
    jne flush 
good: 
    pop eax ; restore length from first sys_read 

而不是在.bss(或.data)中定義dummy_buf,我們可以把它放在堆棧上 - 試圖在這裏保持簡單。這是不完美的 - 我們不知道我們的字符串是否是換行符終止的,並且我們不檢查錯誤(不可能從stdin讀取)。你會發現你正在編寫更多的代碼來處理錯誤和「白癡用戶」輸入,而不是「做這項工作」。必然! (這是一種低級語言 - 我們必須告訴CPU每一件事!)

sys_write不知道零終止的字符串!它會打印edx字符,不管可能有多少垃圾。你想知道你真正想要打印多少個字符,並把它放在edx中(這就是爲什麼我保存/恢復了上面的原始長度)。

您提到「整數」並使用num作爲變量名稱。這些函數都不知道「數字」,除非ascii代碼。你正在閱讀和寫字。將單位數字轉換爲字符和從字符轉換很容易 - 加上或減去'0'(48小數或30小時)。多位數字更復雜 - 環顧四周,如果這是你需要的。

最佳, 弗蘭克