Язык ассемблера: как печатать строку по вертикали? - PullRequest
1 голос
/ 19 мая 2019

Я пытаюсь отредактировать традиционную программу «Hello, world», чтобы она печаталась вертикально, например:

H

е

л

л

о

ш

о

г

л * * тысяча двадцать-одина * 1 022 * D

!

Мне нужно сделать это, используя какие-то инструкции цикла, но я не совсем уверен, что происходит не так.

section .data
    text db "Hello, World!",10,0

section .text
    global _start

_start:
    mov rax, text
    call _print

    mov rax, 60
    mov rdi, 0
    syscall

_print:
    push rax
    mov rbx, 0

_printLoop:
    inc rax
    inc rbx
    mov cl, [rax]
    cmp cl, 0
    jne _printLoop

    mov rax, 1
    mov rdi, 1
    pop rsi
    mov rdx, rbx
    syscall

    ret

1 Ответ

1 голос
/ 19 мая 2019

Системный вызов print не добавляет автоматически новую строку, вам нужно будет использовать буфер, в котором вы можете создать новую строку. Я пытался сохранить большую часть вашей структуры.

section .data
  text db `Hello, World!\n\0`

section .bss
  buffer resb 32

section .text
  global _start

_start:
  mov rax, text
  mov rbx, buffer
  call _print

  mov rax, 60
  mov rdi, 0
  syscall

_print:
  push rbx
  mov rdx, 0

_printLoop:
  mov byte [rbx], `\n`
  inc rbx
  mov cl, [rax]
  mov byte [rbx], cl
  inc rbx
  inc rax
  add rdx, 2
  cmp cl, 0
  jne _printLoop

  mov rax, 1
  mov rdi, 1
  pop rsi
  syscall

  ret

В этой функции rdx отслеживает количество записанных символов, rbx указывает на текущий символ, записываемый в буфер, а rax указывает на текущий символ, читаемый из исходной строки.

В сторону:

  • Вместо использования mov register, 0 предпочитает xor register, register, если только изменение флагов не будет проблематичным, это на порядок быстрее и меньше.
  • Вместо использования cmp register, 0 используйте test register, register, это быстрее и меньше.
  • У вас есть много регистров в x86-64, таких как r8, которые вы могли бы использовать вместо стека, который намного медленнее
...