2013-04-21 94 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 

请记住,这不是一个完整的程序。它完全没有错误处理,不提供用户指令等。它只是方法的一个例证。

相关问题