2013-11-29 130 views
0

我設法在我的64位Linux系統上編寫一個NASM程序,該程序從輸入中刪除非字母符號並在單獨的行中打印每個單詞。問題是我得到了RCX = -1,在這裏我必須得到相應的字符數,結果我得到了分段錯誤。我已經花了數小時試圖找出如何解決這個錯誤。希望你們能幫助我。提前致謝。64位NASM文件處理問題

繼承人我的代碼:

section .data 

file1 db "data", 0 
file2 db "results", 0 

text  times 255 db 0 
textSize equ $ - text 
buff  times 255 db 0 
buffSize equ $ - buff  


section .text 
global main 
main: 
    mov   rax, 2 
    mov  rdi, file1 
    mov  rsi, 0   ;read only 
    mov  rdx, 0x7777 
    syscall     ;open file1 
    mov  rbx, rax  ;save fd to rbx 
    mov  rsi, text   ; a pointer to the current character 

    mov  rax, 0 
    mov  rdi, rbx  ;fd of file1 
    mov  rsi, text 
    mov  rdx, textSize 
    syscall     ;read the text from file1 

    mov  rax, 3 
    mov  rdi, rbx 
    syscall     ;close file1 

    mov  rcx, rax  ; rcx - character counter 

    mov  rbx, buff  ;rbx will be our buffer 

    cmp  rcx, 0 
    je  exit   ; if nothing to read - exit 

process_loop1: 
    mov  dl, byte[rsi] 

    cmp  byte[rsi], 0x41  ; "A" 
    jl  inc1 
    cmp  byte[rsi], 0x5a  ; "Z" 
    jle  save 
    cmp  byte[rsi], 0x61  ; "a" 
    jl  inc1 
    cmp  byte[rsi], 0x7a  ; "z" 
    jle  save 
    jmp  inc1    ;check text 

inc1: 
    inc  rsi 
    dec  rcx 
    jnz  process_loop1 
    jmp  print 

save:     
    mov  byte [ebx], dl 
    jmp  inc2   ;save letters 


inc2: 
    inc  rsi 
    inc  rbx 
    dec  rcx 
    jnz  process_loop2 
    jmp  print 



process_loop2: 
    mov  dl, byte[rsi] 

    cmp  byte[rsi], 0x41  ; "A" 
    jl  enter 
    cmp  byte[rsi], 0x5a  ; "Z" 
    jle  save 
    cmp  byte[rsi], 0x61  ; "a" 
    jl  enter 
    cmp  byte[rsi], 0x7a  ; "z" 
    jle  save 
    jmp  enter 



enter: 
    mov  byte [ebx], 10  ;enter 
    inc  rsi 
    inc  rbx 
    dec  rcx 
    jnz  process_loop1 
    jmp  print 

print:     
    mov   rax, 2 
    mov  rdi, file2 
    mov  rsi, 1  ;write only 
    mov  rdx, 0x7777 
    syscall      ;open file2 
    mov  rbx, rax ;save fd to rbx 


    mov  rax, 1 
    mov  rdi, rbx 
    mov  rsi, buff 
    mov  rdx, buffSize 
    syscall     ;print result 

    mov  rax, 3 
    mov  rdi, rbx 
    syscall     ;close file2 
    jmp  exit 

exit: 
    mov  rax, 60 
    mov  rdi, 0 
    syscall 
+2

爲什麼要使用「神奇數字」?如果您使用'mov rax,sys_open'而不是'mov rax,2',那麼它會不會讓您的代碼自動生成文檔? – Gunner

+0

並且在哪一行中會出現分段錯誤?您是否嘗試在調試器中運行您的程序? (彙編程序員不應該需要手持...) –

+0

我用gdb測試了程序,發現在sys_read調用rax後保存值-1而不是讀取的符號數。我怎麼能得到一些符號? – JulioBordeaux

回答

0

你有sys_read,你嘗試檢查接收的字節數的時間之間的sys_close。因此,您正在檢查close的返回值,而不是讀取值。另外請注意,rcx被系統調用破壞,所以你不能移動mov rcx, rax行。

另外,在一些地方你使用[ebx]而不是[rbx]。

此外,您可能希望使用O_CREAT作爲結果文件,並且只寫入與您處理的字節數相同的數量,而不是buffSize

1
section .data 
    filename db 'AVG.asm' 


section .bss 
    buffer resb 2000 
    fd_in resb 1 

section .text 
    global _start 
_start: 
     mov rax,2 
     mov rdi,filename 
     mov rsi,0 
     mov rdx,0777 
     syscall 

     mov [fd_in],rax 

     mov rax,0 
     mov rdi,[fd_in]  
     mov rsi,buffer 
     mov rdx,2000 
     syscall 


     mov rax,1 
     mov rdi,1 
     mov rsi,buffer 
     mov rdx,2000 
     syscall 



     mov rax,3 
     mov rdi,[fd_in] 
     syscall 

     mov rax,60 
     mov rdi,0 
     syscall 
+0

你應該更多地解釋你在那裏做什麼。提問的人需要從你的答案中學到一些東西。 –