Объединить одну .data и одну .bss строку вместе в сборке x86_64 - PullRequest
0 голосов
/ 06 декабря 2018

Я пишу программу, которая запрашивает ваше имя, а затем печатает его так:

<name> is your name?

Вот мой текущий код:

section .data
    promptText: db "What is your name: ", 0
    promptTextLength: equ $ - promptText
    secondText: db " is your name?", 0

section .bss
    name resb 15

section .text:
    global _start

_start:

    ; Print prompt message
    mov rax, 1
    mov rdi, 1
    mov rsi, promptText
    mov rdx, promptTextLength
    syscall

    ; Get name
    mov rax, 0
    mov rdi, 0
    mov rsi, name
    mov rdx, 15
    syscall

    ; Somehow concatenate "name" and "secondText"

    ; Print second message
    mov rax, 1
    mov rdi, 1
    mov rsi, nameAndSecondText
    mov rdx, nameAndSecondTextLength
    syscall

    ; Exit 0
    mov rax, 60
    mov rdi, 0
    syscall

Итак, довольнодобавьте name и secondText, затем распечатайте их на терминале.

Однако

Я не хочу просто дважды вызывать SYS_WRITE, чтобы напечатать обе строки, мне нужнообъединить name и secondText в их собственную переменную.

Спасибо!

PS Извините, если я использую неправильную терминологию, я привык к языкам более высокого уровня, таким как Python, Cи т. д.

1 Ответ

0 голосов
/ 06 декабря 2018

Вам не нужен завершающий NUL строки, поскольку вы не используете функции, проверяющие этот символ.

Удалите двоеточие в section .text:.Затем вы можете отладить программу с помощью GDB.

Я предлагаю добавить secondText непосредственно к введенному имени.Для этого вам нужно зарезервировать больше места для переменной name.SYS_READ не замечает этого, поэтому после вызова SYS_READ пробел остается пустым.

section .data
    promptText:         db "What is your name: "
    promptTextLength:   equ $ - promptText
    secondText:         db " is your name?", 10
    secondTextLength:   equ $ - secondText

section .bss
    name resb 15 + secondTextLength ; Space for input and appended string

section .text
global _start

_start:

    ; Print prompt message
    mov rax, 1                  ; SYS_WRITE - http://man7.org/linux/man-pages/man2/write.2.html
    mov rdi, 1                  ; fd = STDOUT
    mov rsi, promptText         ; *buf
    mov rdx, promptTextLength   ; Count of bytes to write
    syscall                     ; Call Linux

    ; Get name
    mov rax, 0                  ; SYS_READ - http://man7.org/linux/man-pages/man2/read.2.html
    mov rdi, 0                  ; fd = STDIN
    mov rsi, name               ; *buf
    mov rdx, 15                 ; Max count of bytes to read
    syscall                     ; Call Linux - return EAX = number of bytes read
    dec rax                     ; number of bytes read without ENTER

    ; Append secondText
    mov rsi, secondText         ; *source
    mov rdi, name               ; *dest
    add rdi, rax                ; Set pointer one byte behind the real name
    mov rcx, secondTextLength   ; Count of bytes to copy
    lea rbx, [rax + rcx]        ; Save the total length of the string
    rep movsb                   ; Copy RCX bytes from [RSI] to [RDI]

    ; Print name (input + second message)
    mov rax, 1                  ; SYS_WRITE - http://man7.org/linux/man-pages/man2/write.2.html
    mov rdi, 1                  ; fd = STDOUT
    mov rsi, name               ; *buf
    mov rdx, rbx                ; Count of bytes to write (RBX was saved above)
    syscall                     ; Call Linux

    ; Exit (0)
    mov rax, 60                 ; SYS_EXIT
    mov rdi, 0                  ; Exitcode
    syscall                     ; Call Linux / no return
...