1

かなり単純な問題。

この nasm は、ユーザーが書いたメッセージ (つまり、hello) をファイルに書き込むことになっています。これも、引数からのユーザー入力によって決定されます。これは問題なく実行されますが、問題は、後で使用されないすべての null バイトも書き込まれることです。たとえば、ユーザー入力用に 32 バイトを予約し、ユーザーが入力用に 4 バイトしか使用しない場合、バイト用のバイトが 28 ヌル バイトと共に出力されます。

null バイトの出力を停止するにはどうすればよいですか?

使用したコード:

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

まあ、ヘッダーファイルを掘り下げて実験した後、私は自分でそれを理解しました。

基本的には、ユーザーの文字列をバイト カウント プロセスに通す必要があります。バイト カウント プロセスは、文字列に沿って null バイトが見つかるまでカウントし、その数の null 以外のバイトを格納します。

私と同じ問題を抱えている人のために、私が使用している回避策を投稿します。このソリューションは32ではなく 64 ビットの nasm 用であることに注意してください。

32 ビット コーダーの場合は、次のように変更します。

  • 「rax」と「eax」のすべてのインスタンス
  • 「ebx」を含む「rdi」のすべてのインスタンス
  • 「ecx」を含む「rsi」のすべてのインスタンス
  • 「rdx」と「edx」のすべてのインスタンス
  • "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 に答える