Более эффективный способ вывести целое число в чистой сборке - PullRequest
3 голосов
/ 07 ноября 2010

Я хочу вывести целое число, используя чистую сборку.Я использую Nasm на 64-битной машине Linux.В настоящее время я ищу способ вывода целых чисел для отладки компилятора, но я хочу использовать тот же код для написания ОС, что также является причиной, по которой я не просто использую printf().После долгих поисков и разочарований я пришел с этим кодом

    SECTION .data
var:    db  "      ",10,0

    SECTION .text
global main
global _printc
global _printi

main:
    mov rax, 90
    push    rax
    call    _printi

    xor rbx, rbx
    mov rax, 1
    int 0x80

_printi:
    pushf
    push    rax
    push    rbx
    push    rcx
    push    rdx

    mov rax, [rsp+48]
    mov rcx, 4
.start:
    dec rcx
    xor rdx, rdx
    mov rbx, 10
    div rbx
    add rdx, 48
    mov [var+rcx], dl
    cmp rax, 0
    jne .start

    mov rax, [var]
    push    rax
    call    _printc
    pop rax

    pop rdx
    pop rcx
    pop rbx
    pop rax
    popf
    ret

_printc:
    push    rax
    push    rbx
    push    rcx
    push    rdx

    mov rax, [rsp+40]
    mov [var], rax
    mov rax, 4
    mov rbx, 1
    mov rcx, var
    mov rdx, 4
    int 0x80

    pop rdx
    pop rcx
    pop rbx
    pop rax
    ret

Обратите внимание, что я буду заменять вызовы 0x80 на вызовы BIOS при портировании на разработку ОС.оптимизировать или даже оптимизировать этот код в дальнейшем.Моей первой мыслью было бы заменить нажатие всех регистров по отдельности, но там нет 64-битной pusha инструкции ...

1 Ответ

2 голосов
/ 07 ноября 2010

Вот некоторые возможные изменения в программе:

_printi:
    pushf
    push    rax
    push    rbx
    push    rcx
    push    rdx

    mov rax, [rsp+48]
    mov rcx, 4
    mov rbx, 10 ; --moved outside the loop
.start:
    dec rcx
    xor rdx, rdx
    div rbx
    add rdx, 48
    mov [var+rcx], dl
    cmp rax, 0
    jne .start

    ; mov rax, [var] -- not used
    ; push    rax -- not used
    call    _printc
    ; pop rax -- not used

    pop rdx
    pop rcx
    pop rbx
    pop rax
    popf
    ret

Я также отметил некоторые ограничения в алгоритме.Если число больше 9999, код будет продолжать вводить цифры за пределами выделенного пространства, перезаписывая некоторые другие данные.Подпрограмма не может быть использована повторно, то есть если вы напечатаете 123, то 9 получится как 129.

...