Сборка «Ошибка сегментации» при попытке печати десятичного числа - PullRequest
0 голосов
/ 10 сентября 2018

Я пытаюсь создать макрос, который будет печатать для меня десятичное число. Моя идея состояла в том, чтобы разделить число на десять, преобразовать остаток в ASCII и поместить его в стек до тех пор, пока соотношение не станет равным 0. Затем я печатаю цифры по одной, но по какой-то причине я получаю «Ошибка сегментации».

Я использую Linux, nasm и процессор x86_64.

%macro printInt 1
    mov rax, %1
    mov rbx, 0
%%loop1:                  ;Convert all digits to ascii
    inc rbx               ;Count of the digits in number
    mov rdx, 0
    div rax
    add rdx, 48           ;Convert remainder to ascii
    push rdx              ;Push remainder into stack
    cmp rax, 0            ;Compare ratio to 0
    jne %%loop1
%%loop2:                  ;Print the number digit by digit
    dec rbx

    mov rax, 1            ;Sys_Write
    mov rdi, 1            ;STDOUT
    pop rsi               ;Pop digit
    mov rdx, 1
    syscall

    cmp rbx, 0
    jne %%loop2
%endmacro

section .data
    number1 db 123

section .text
    global _start
_start:

    printInt number1

    mov rax, 60
    mov rdi, 0
    syscall

Любая помощь приветствуется, спасибо заранее!

1 Ответ

0 голосов
/ 10 сентября 2018

Первая ошибка:

number1 db 123

number1 определяется как БАЙТ, но будет рассматриваться как QUADWORD (mov rax, %1).Измените его на

number1 dq 123

Вторая ошибка:

printInt number1

Макрос получает аргумент в виде строки.Итак, mov rax, %1 будет решено до mov rax, number1.В NASM RAX получит адрес number1, а не значение.Измените его на

printInt [number1]

Третья ошибка:

div rax

означает: Разделить RDX: RAX на RAX, сохранить результат в RAX и остаток в RDX.Это всегда приводит к RAX = 1 и RDX = 0.Используйте другой регистр со значением 10.

Четвертая ошибка:

pop rsi

Подпрограмма ядра SYSCALL / RAX = 1 ожидает указатель в RSI, а нечисло.Есть несколько способов решения проблемы.Я оставляю это вашему воображению.

...