Почему я получил ошибку сегментации? - PullRequest
2 голосов
/ 21 апреля 2020

Я новичок в программировании сборки. Я пытаюсь сделать простую программу в сборке x64 для печати перевернутого треугольника на консоли. Я ожидаю, что моя программа выведет что-то вроде этого:

********
 *******
  ******
   *****
    ****
     ***
      **
       *

Пока это мое усилие:

;--------------------------------------
; compile and run:
; $ nasm -f elf64 invtriangle.asm
; $ ld -s -o invtriangle invtriangle.o
; $ ./invtriangle
;--------------------------------------

                bits 64
                global _start

                section .text
_start:
                mov     r8, 0          ; copy maximum number of whitespace characters allowed for first line to register 'r8'
                mov     r9, 8          ; copy maximum number of stars allowed for first line to register 'r9'
                mov     r10, 0         ; number of whitespace characters written on line so far
                mov     r11, 0         ; number of star characters written on line so far
                mov     rbx, output    ; copy address of the string pointer to register 'rbx'
writeline:
writewhitespace:
                cmp     r8, 0          ; check if the value of register 'r8' is zero
                je      writestars     ; if so, skip writing whitespaces
                mov     byte[rbx], ' ' ; write a whitespace character
                inc     rbx            ; advance pointer to next address to write
                inc     r10            ; increment number of whitespace characters written on line so far by 1
                cmp     r10, r8        ; compare register values: check if we reached the maximum number of whitespace characters allowed for the current line
                jne     writewhitespace; if not, continue writing whitespaces
writestars:
                mov     byte[rbx], '*' ; write s star
                inc     rbx            ; advance pointer to next address to write
                inc     r11            ; increment number of star characters written on line so far by 1
                cmp     r11, r9        ; compare register values: check if we reached the maximum number of star characters allowed for the current line
                jne     writestars     ; if not, continue writing stars
lineend:
                mov     byte[rbx], 10  ; write a new line character (ascii value for new-line is 10)
                inc     rbx            ; advance pointer to next address to write
                inc     r8             ; the next line will be one whitespace longer
                dec     r9             ; the next line will be one star shorter
                mov     r10, 0         ; reset the counter (number of whitespace characters written on line)
                mov     r11, 0         ; reset the counter (number of star characters written on line)
                cmp     r8, maxlines   ; did we exceed the maximum number of lines?
                jng     writeline      ; if not, continue writing lines
                mov     rax, 1         ; system call for write (64 bit)
                mov     rdi, 1         ; file descriptor = stdout
                mov     rsi, output    ; copy the address of string 'output' to output
                mov     rdx, nbytes    ; copy number of bytes in output
                syscall                ; invoke OS to write
                mov     rax, 60        ; system call for exit (64 bit)
                mov     rdx, 0         ; exit status = 0
                syscall                ; invoke OS to exit

                section .bss
maxlines        equ     8              ; maximum number of lines to write
nbytes          equ     72             ; (8 + 8 + 8 + 8 + 8 + 8 + 8 + 8) + 8 = 72 bytes (don't forgot to take account of new-line characters!)
output          resb    nbytes         ; initialize a string pointer by reserving number of bytes

Когда я запускаю программу сборки, описанную выше, я продолжаю получать ошибку сегментации, и я не могу понять причину этого. Я попытался изменить регистры, и я получил тот же результат. Интересно, что когда я увеличил максимальное число звезд, разрешенное для первой строки, с 8 до 10 в регистре r9, программа работала без ошибки сегментации, но результат оказался не таким, как я ожидал (я не знаю, почему это произошло). Я не уверен, правильно ли я вычислил переменную nbytes в разделе bss. Я буду признателен за любую помощь, спасибо!

Я использую 64-битную ОС Ubuntu для запуска вышеуказанной программы.

1 Ответ

1 голос
/ 21 апреля 2020

Подсказка: что происходит с вашим writestars l oop в последней строке, когда должны быть напечатаны ноль звездочек (так что r9 равно 0)?

...