1

很简单的问题。

这个 nasm 应该将用户编写的消息(即 hello)写入文件,再次由用户输入的参数确定。它这样做很好,但问题是,它也会写入所有未使用的空字节。例如,如果我为用户输入保留了 32 个字节,而用户只使用了 4 个字节作为输入,那么这些字节将连同 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
4

1 回答 1

0

好吧,在对头文件进行了一些挖掘和试验之后,我自己弄清楚了。

基本上,它的工作方式是您必须将用户的字符串通过一个字节计数过程,该过程沿字符串计数,直到找到一个空字节,然后存储该数量的非空字节。

我将发布我正在为与我有同样问题的任何人使用的解决方法。请记住,此解决方案适用于 64 位 nasm,而不是 32

对于 32 位编码器,更改:

  • 所有带有“eax”的“rax”实例
  • 带有“ebx”的“rdi”的所有实例
  • 带有“ecx”的“rsi”的所有实例
  • 带有“edx”的“rdx”的所有实例
  • 带有“int 80h”(或等效项)的“syscall”的所有实例
  • 所有带有“edx”的“r8”实例(你必须兼顾这个和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

请记住,这不是一个完整的程序。它完全缺乏错误处理,不提供用户指令等。它只是方法的说明。

于 2013-04-22T21:13:25.280 回答