compiler-construction - 在纯汇编中输出整数的更有效方法

标签 compiler-construction performance x86-64 nasm

我希望使用纯汇编输出一个整数。我在 64 位 Linux 机器上使用 nasm。目前我正在寻找一种输出整数来调试编译器的方法,但我想使用相同的代码来编写操作系统,这也是我不简单地使用 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

请注意,在移植到操作系统开发时,我将用 BIOS 调用替换 0x80 调用。

我的问题是如何进一步优化甚至美化这段代码。我的第一个想法是替换单独推送所有寄存器,但没有任何 64 位 pusha指令...

最佳答案

以下是对例程的一些可能更改:

_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。

关于compiler-construction - 在纯汇编中输出整数的更有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4117422/

相关文章:

c++ - 使用 Intel Pin 时跟踪不匹配的 CALL 和 RET 指令数

javascript - `goal symbol` 与上下文无关语法中的 `start symbol` 相同吗

android - 后台粘性并发标记清除 GC 已释放

java - 最大 jvm 堆的大小未达到或接近机器上的最大物理内存的原因是什么?

javascript - JQuery 和 IE 的性能极度下降

c - 如何以编程方式禁用不可屏蔽中断?

汇编和多核 CPU

JAVA 编译器 API - 无法找到外部类文件

c - 第一个 C 编译器是如何编写的?

compiler-construction - 为什么 Julia 编译器不优化这个循环?