2015-05-30 73 views
0

我想從輸入文件中讀取字符,並將它們放在數組中(除了新行字符)。爲數組賦值 - Assembly

這裏是我的代碼:

mov dword [counter], 0 
    mov edi, [size] 
loop: 
    mov esi, state 
    cmp [counter], edi ; read all chars of the file 
    je end_loop 
    pushad 
    mov eax, 3 
    mov ebx, dword [file_desc] 
    mov ecx, read_char 
    mov edx, 1 
    int 0x80 
    popad 

    cmp byte [read_char], '1' 
    je put_char 
    cmp byte [read_char], ' ' 
    je put_char 
    jmp loop 

put_char: 
    mov edx, [read_char] 
    mov [esi + counter], edx 

    ;; print number of char read from 0 to size-1 
    pushad 
mov ecx, dword [counter] 
push ecx 
push printInt 
call printf 
add esp, 8 
popad 

;; print char read 
    pushad 
    push edx 
    push printChar 
    call printf 
    add esp, 8 
    popad 

    ;; print value stored in state[counter] 
    pushad 
    push dword [esi + counter] 
    push printChar 
    call printf 
    add esp, 8 
    popad 

    mov eax, [counter] 
    inc eax 
    mov [counter], eax 

    jmp loop 
end_loop: 

循環內的打印工作得很好,因爲我得到的字符數,剛纔我看到的字符和[ESI +計數器]炭(應該是狀態[計數器])。

然而,試圖讀取循環後打印出來,與此代碼:

mov dword [counter], 0 
    mov edi, [size] 
printarray: 
    mov esi, state 
    cmp [counter], edi 
    je end 

    pushad 
    push dword [esi + counter] 
    push printChar 
    call printf 
    add esp, 8 
    popad 

    pushad 
    mov ecx, [counter] 
    inc ecx 
    mov [counter], ecx 
    popad 
    jmp printarray 
end: 

我得到的是空白(新焦線的每一行,從我printChar)。

我不明白我讀的值不存儲在數組中。 end loopmov dword [counter], 0之間沒有代碼,就在printarray循環之前。

僅僅是我的數據和BSS:

section .data 
newLine: DB "", 10, 0 
printInt: DB "%d", 10, 0 
printString: DB "%s", 10, 0 
printChar: DB "%c", 10, 0 
hello:  DB "hello", 10, 0 

section .bss 
file_name resb 80 
file_desc resd 1 
WorldLength resd 1 
WorldWidth resd 1 
generations resd 1 
print_freq resd 1 
state resb 60*60 
read_char resb 1 
counter resd 1 
size resd 1 

謝謝您的幫助。

回答

0

那麼......

首先,在字節上操作時不要使用32位寄存器。我相信即使你的代碼工作,一些數據也會被覆蓋。

我相信你的問題的地方居住在類似這些

mov [esi + counter], edx 
... 
push dword [esi + counter] 

實際上他們的意思聲明:「採取對抗的地址,並將其添加到ESI」,我認爲這是不是你想要的。

走上這一點, - 由字符讀取文件的字符是非常低效的 - 使用代替ECX計數器變量是低效 - 遞增寄存器,而不是一個內存位置iself是低效太

我試着儘可能地重寫你的代碼,我希望這是值得的。

mov eax, 3 
mov ebx, dword [file_desc] 
mov ecx, state 
mov edx, [size] 
int 0x80 
; eax now contains the number of bytes read, so why not to use it? 

mov ebx, eax 
add ebx, state 
mov byte [ebx], 0x0 ; this will be end-of-string, although it may not really be necessary 

xor ecx, ecx ; this will be our counter now 
_loop:   ; loop is actually an instruction 
    cmp ecx, eax 
    je _end 
    inc ecx  ; ecx++ 

    mov dl, '\n' 
    cmp byte [state + ecx], dl  ; is newline? 
    jne _loop      ; nope? ok, try again 

    mov dl, ' '      ; yes? 
    mov byte [state + ecx], dl  ; replace newline with space character 
    jmp _loop 
_end: 

; print the result 
mov edx, eax ; the size - number of bytes read 
mov eax, 4 
mov ebx, dword [file_desc] 
mov ecx, state 
int 0x80 
+0

爲什麼如果字節是不是新線我應該跳回循環?這些是我想要閱讀的字符。此外,我知道該文件只包含空格,一個和新行字符。 雖然我會嘗試這個,謝謝 –

+0

順便說一句,大小不是多少個字,但是寫多少字,它有什麼區別? –

+0

你只寫出了你讀過的內容,因爲上面的代碼只用空格替換了新行。 – user35443

0

問題解決了。 我應該用這把字符數組中:

put_char: 
mov dl, [read_char] 
mov [esi], dl 

mov eax, [counter] 
inc eax 
mov [counter], eax 
inc esi 

jmp loop 

我刪除了打印,那些僅用於調試。

謝謝:)

+1

無論如何,請記住你可以直接使用'inc dword [counter]'。 – user35443