2013-04-21 50 views
1

很簡單的問題。如何在不寫入空字節的情況下寫入nasm?

這個nasm應該寫一個用戶編寫的消息(即hello)給一個文件,這個文件又是由一個參數的用戶輸入決定的。它這樣做很好,但問題是,它會寫入所有之後未使用的空字節。例如,如果我爲用戶輸入保留32個字節,並且用戶僅使用四個字符輸入,那麼將打印字節數據以及28個空字節。

如何停止打印空字節?使用

代碼:

global _start 

section .text 
_start: 

    mov rax, 0 ; get input to write to file 
    mov rdi, 0 
    mov rsi, msg 
    mov rdx, 32 
    syscall 

    mov rax, 2 ; open the file at the third part of the stack 
    pop rdi 
    pop rdi 
    pop rdi 
    mov rsi, 1 
    syscall 

    mov rdi, rax 

    mov rax, 1 ; write message to file 
    mov rsi, msg 
    mov rdx, 32 
    syscall 

    mov rax, 3 ; close file 
    syscall 

    mov rax, 1 ; print success message 
    mov rdi, 1 
    mov rsi, output 
    mov rdx, outputL 
    syscall 

    mov rax, 60 ; exit 
    mov rdi, 0 
    syscall 

section .bss 
    msg: resb 32 

section .data 
    output: db 'Success!', 0x0A 
    outputL: equ $-output 

回答

0

好了,在做頭文件一些挖掘和實驗後,我想通了我自己。

基本上,它的工作方式是,你必須通過一個字節計數進程來計算用戶的字符串,該進程會沿着字符串進行計數,直到找到一個空字節,然後存儲該非空字節數。

我會發布解決方案,我用於任何與我有同樣問題的人。請記住,此解決方案適用於64位nasm,不是32

對於32位編碼器,變化:

  • 「RAX」 與 「EAX」
  • 的所有實例 「RDI」 與 「EBX」
  • 「RSI」 的所有實例的所有實例與 「ECX」
  • 「RDX」 的所有實例 「EDX」
  • 與 「INT 80H」(或equivelant)
  • 與 「EDX」 所有 「R8」 的情況下的 「系統調用」 的所有實例(您必須j uggle這和RDX)

這是我使用的解決方案,在充分:

global _start 

; stack: (argc) ./a.out input filename 

section .text 
_start: 

getInput: 
    mov rax, 0 ; syscall for reading user input 
    mov rdi, 0 
    mov rsi, msg ; store user input in the "msg" variable 
    mov rdx, 32 ; max input size = 32 bytes 
    xor r8, r8 ; set r8 to zero for counting purposes (this is for later) 

getInputLength: 
    cmp byte [msg + r8], 0 ; compare ((a byte of user input) + 0) to 0 
    jz open    ; if the difference is zero, we've found the end of the string 
          ; so we move on. The length of the string is stored in r9. 
    inc r8     ; if not, onto the next byte... 
    jmp getInputLength  ; so we jump back up four lines and repeat! 

open: 
    mov rax, 2 ; syscall for opening files 
    pop rdi 
    pop rdi 
    pop rdi ; get the file to open from the stack (third argument) 
    mov rsi, 1 ; open in write mode 
    syscall 

    ; the open syscall above has made us a full file descriptor in rax 

    mov rdi, rax ; so we move it into rdi for later 

write: 
    mov rax, 1 ; syscall for writing to files 
       ; rdi already holds our file descriptor 
    mov rsi, msg ; set the message we're writing to the msg variable 
    mov rdx, r8 ; set write length to the string length we measured earlier 
    syscall 

close: 
    mov rax, 3 ; syscall for closing files 
       ; our file descriptor is still in fd 
    syscall 

exit: 
    mov rax, 60 ; syscall number for program exit 
    mov rdi, 0 ; return 0 

請記住,這不是一個完整的程序。它完全沒有錯誤處理,不提供用戶指令等。它只是方法的一個例證。

相關問題