在纯汇编中输出整数的更有效方法
我希望使用纯汇编输出一个整数。我在 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
指令...
I'm looking to output an integer using pure assembly. I'm using nasm on a 64-bit linux machine. At the moment I'm looking for a way to output integers to debug a compiler, but I want to use the same code for writing an OS, which is also the reason I don't simply use printf()
. After much searching and frustration I have come up with this code
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
Note that I'll be replacing 0x80 calls with BIOS calls when porting to OS development.
My question is how to optimize, or even prettify, this code further. My first thought would be to replace pushing all the registers individually, but there isn't any 64-bit pusha
instruction...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
以下是例程的一些可能的更改:
我还注意到算法中的一些限制。如果数字大于 9999,代码将继续将数字放入分配的空间之外,覆盖其他一些数据。该例程不完全可重用,即如果您打印 123,则 9 将显示为 129。
Here are some possible changes to the routine:
I also noted some limitations in the algorithm. If the number is larger than 9999, the code will continue to put digits outside of the allocated space, overwriting some other data. The routine is not fully reusable, i.e. if you print 123, then 9 it will come out as 129.