【问题标题】:Assembly Printing A String Efficiently组装高效地打印字符串
【发布时间】:2019-04-23 12:33:39
【问题描述】:

所以我目前正在处理一个简单的程序集块,我希望将其变成一个高效的引导加载程序来加载 C 内核。

我现在的主要问题是。是否有任何关于我当前如何从 SI 寄存器中存储和打印字符串的指针?

它完美地呈现了字符串。我只是想确保我正在开发良好的做法。

这是我的代码。

ORG 0x7c00
msg db 'Hello World!', 0

start:
    mov ax, 0x00
    mov ds, ax
    mov ah, 0x0e ;prepare AH register to be written to.
    mov si, msg ;move string into SI register and prepare for read/write
    call print

print:
    lodsb ;load byte string pointed to in SI and DS register
    or al, al ;check if al equals 0
    jz end ; if zero, end execution
    int 0x10 ;print string
    jmp print ;^ above line and this only execute if AL > 0.

end:
    hlt
    jmp end

times 510-($-$$) db 0
dw 0xaa55

【问题讨论】:

  • 没有人关心在使用 bios 服务启动期间打印字符串的效率。绝对不好的做法是在不是函数的东西上使用call。此外,您不应将数据放在0x7c00,因为这是引导扇区的入口点(无论您可能在哪里放置start 标签),因此cpu 将尝试执行任何代码.意思是,将msg 移动到jmp end 之后,使其不在执行路径中。
  • 在引导加载程序中,唯一重要的“效率”衡量标准是代码大小。由于限制为 510 字节,您需要以尽可能少的代码字节完成工作。也就是说,您的代码在代码大小和效率方面都很糟糕。 xor ax,axmov ax,0 短,根本不需要使用call。只是陷入循环。 or al,al 的大小相同,但比 test al,al 差,而且您知道第一个字节不是终止符,因此您可以对其进行重构:Why are loops always compiled into "do...while" style?
  • 另请参阅Tips for golfing in x86/x64 machine code 了解更多信息。您可以考虑在循环底部使用缓慢但很小的 loop 指令。当然,为了提高效率,如果 BIOS 具有一次调用打印多个字符的任何功能,那将快得多int 是一条很慢的指令,因此只为整个字符串创建一条指令要快得多。

标签: assembly x86 kernel bios


【解决方案1】:

您的代码应如下所示。

    org     0x7c00

    xor     ax, ax
    mov     ds, ax
    jmp     Begin

print:
    mov     ah, 0x0e            ; BIOS TTY function
.L0:
    lodsb
    or      al, al
    jnz     .J0
    ret
.J0:
    int     0x10
    jmp     .L0

Prompt:
     db     'Hello World', 0

Begin:
    mov     si, Prompt
    call    print
.spin:
    hlt
    jmp     .spin

    times 510 - $+$$ db 0

    dw      0xAA55

因为您不会跳过提示文本,这就是计算机认为它需要在 BIOS 将控制权传递给引导扇区后立即执行的内容。

00  48                dec ax
01  656C              gs insb
03  6C                insb
04  6F                outsw
05  20576F            and [bx+0x6f],dl
08  726C              jc 0x76
0A  6490              fs nop

除此之外,我所做的唯一更改是在循环中初始化 AH,否则每次调用该函数时都必须重复设置 AH。

我有几个版本的引导加载程序,在每个版本中,我都特别注意优化,尤其是当它适用于空间时,因为只有这么多可以适合一个扇区。

这可能有一些变体,但重要的是控制流遵循可预测的路径。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    相关资源
    最近更新 更多