мой ассемблерный код учитывает один дополнительный байт для длины строки - PullRequest
1 голос
/ 30 октября 2019

Я написал следующий код, чтобы прочитать текст, вычислить длину и сообщить о ней. Для простоты кода я предполагаю, что длина строки не превышает 10 символов.

Код, который я использую для сборки:

nasm -f elf64 strlen.asm && ld strlen.o -o strlen && ./strlen

У меня два вопроса:

  1. Этот код скомпилирован как 64-битный, а сам код 32-немного. Какие изменения я должен применить, чтобы сделать этот код 64-битным тоже?
  2. Почему приложение всегда сообщает длину в один байт дополнительно? Теоретически, это не считается нулевым завершением. Включает ли данный текст \x10 или \x13?
section .text
global _start

_start:

; show prompt message
    mov     edx, 19     ; number of bytes to write - one for each letter plus 0Ah (line feed character)
    mov     ecx, txt_prompt    ; move the memory address of our message string into ecx
    mov     ebx, 1      ; write to the STDOUT file
    mov     eax, 4      ; invoke SYS_WRITE (kernel opcode 4)
    int     80h

; read the user input
    mov eax, 3          ; Read user input into str
    mov ebx, 0          ; |
    mov ecx, user_input        ; | <- destination
    mov edx, 100        ; | <- length
    int 80h             ; \

; calculate the length

    mov     ebx, user_input        ; move the address of our message string into EBX
    mov     eax, ebx        ; move the address in EBX into EAX as well (Both now point to the same segment in memory)

strlen_nextchar:
    cmp     byte [eax], 0   ; compare the byte pointed to by EAX at this address against zero (Zero is an end of string delimiter)
    jz      strlen_finished        ; jump (if the zero flagged has been set) to the point in the code labeled 'finished'
    inc     eax             ; increment the address in EAX by one byte (if the zero flagged has NOT been set)
    jmp     strlen_nextchar        ; jump to the point in the code labeled 'strlen_nextchar'

strlen_finished:
    sub     eax, ebx        ; subtract the address in EBX from the address in EAX
    add     byte [txt_output+33], al

; show output message
    mov     edx, 34     ; number of bytes to write - one for each letter plus 0Ah (line feed character)
    mov     ecx, txt_output    ; move the memory address of our message string into ecx
    mov     ebx, 1      ; write to the STDOUT file
    mov     eax, 4      ; invoke SYS_WRITE (kernel opcode 4)
    int     80h

; exit code
    mov     ebx, 0
    mov     eax, 1
    int     80h

section .data
txt_prompt:   db      'Enter your message:', 0Ah
txt_output:   db      'The string length is calculated: 0', 0Ah

section .bss
user_input: resb 100


...