Assembly 在NASM中有没有办法将整数转换为十六进制?
有人能给我解释一下,是否有办法得到一个十进制值(0-9)?我正在做的一个项目需要它。我想做Assembly 在NASM中有没有办法将整数转换为十六进制?,assembly,decimal,nasm,x86-16,Assembly,Decimal,Nasm,X86 16,有人能给我解释一下,是否有办法得到一个十进制值(0-9)?我正在做的一个项目需要它。我想做movsi,[CX:DX],但后来我有一种感觉,那是行不通的。所以我决定在网上搜索,但是我想要的主题没有出现。有人能告诉我有没有办法从0到9得到1个十进制值 我试过: MOV BL,1000 MOV-AH,00h DIV DX 我做错什么了吗 使用16位代码的编译器NASM。从注释中可以看出,您想要的是: ;Input ; cx Clock ticks since midnight ; ;Output
movsi,[CX:DX]
,但后来我有一种感觉,那是行不通的。所以我决定在网上搜索,但是我想要的主题没有出现。有人能告诉我有没有办法从0到9得到1个十进制值
我试过:
MOV BL,1000
MOV-AH,00h
DIV DX
我做错什么了吗
使用16位代码的编译器NASM。从注释中可以看出,您想要的是:
;Input
; cx Clock ticks since midnight
;
;Output
; ax Most significant non-zero decimal digit of clocks since midnight (unless
; clocks since midnight is zero, where zero will be returned)
;
;Trashed
; none (contents of all registers not used for outputs are preserved)
get_most_significant_decimal_digit:
mov ax,cx ;ax = numerator = clocks since midnight
cmp ax,10 ;Is it already small enough?
jb .done ; yes
push bx
push dx
mov bx,10 ;bx = divisor (constant value 10)
.continue:
xor dx.dx ;dx:ax = numerator zero extended to 32 bits
div bx ;ax = numerator / 10
cmp ax,10 ;Is it small enough now?
jae .continue ; no, keep going
pop dx
pop bx
.done:
ret
注意:为了获得最佳性能,可能最好为每个除法使用不同的除数,选择除数以最小化除法的数量。例如,“如果不小于10000,则除以10000”,然后“如果不小于100,则除以100”,然后“如果不小于10,则除以10”。很难说性能改进是否值得所需的额外复杂性(以及更差的代码可读性)
再三考虑;它并没有那么凌乱(未经测试,NASM语法):
对于这个替代方案,“更糟的情况”是3个部门和3个分支机构(而不是之前方法中的4个部门和5个分支机构)。从何处获得?总之,一般来说,用10除的余数。这不太清楚。1个十进制数字0-9在十六进制中具有相同的值,因此无需转换。要得到一个数字,使用模10。您可能希望在
cx
中提供示例输入,在si
中提供预期输出,以便我们更好地理解。那么您想要最有效的十进制数字?一种选择是将输入除以10000。如果商不是零,那就是你的结果。否则,将余数除以1000,再除以100,再除以10。请注意,如果您对每次只需除以10感到满意,则以相反的顺序进行操作更简单。除非您实际输出结果,否则您肯定会看到黑屏。但这是一个完全不同的问题。回复:标题问题:,或(16位)。但那似乎不是你要做的?用于从寄存器中的整数中提取以10为基数的数字,或者用于在比较/分支链之后只除法一次的性能。或者使用一个将值乘以10的循环(从1或10开始)并进行比较,当发现10的幂大于输入并使用上一个幂时停止。(或乘以10溢出)在更新中,您可以提升分支链前面的xor dx,dx
。代码大小与div
执行次数之间的有趣权衡;如果div
不比mul或code fetch慢很多,并且对很多情况都有好处,那就可以了。@PeterCordes:你可以有一个分支树,树中的每个“结束节点”都做一个除法;但这将是“额外的复杂性(以及更差的代码可读性)”,而且(取决于调用的频率)甚至可能会使性能更差(例如,预测失误的分支的成本高于2个分区)。@PeterCordes:是的,有很多替代方法(另一种方法类似于“if(ticks<10))返回ticks;else返回表[ticks/2-5];
“以减少表格大小);但大多数情况下,我只是在等待最初的提问者意识到他们的问题并没有反映出他们真正想要的(要么是因为他们希望所有数字都是“整数到十进制ASCII”,要么是因为他们记得BIOS“从午夜开始的滴答声”实际上是cx:dx
中的32位值,而不是16位)。)@SepRoland:对于该代码,不需要const1000:dw 1000
(从1000到9999的值将除以100,然后再除以10)。
section .data
const10000: dw 10000
const100: dw 100
const10: dw 10
section .text
;Input
; cx Clock ticks since midnight
;
;Output
; ax Most significant non-zero decimal digit of clocks since midnight (unless
; clocks since midnight is zero, where zero will be returned)
;
;Trashed
; none (contents of all registers not used for outputs are preserved)
get_most_significant_decimal_digit:
mov ax,cx ;ax = numerator = clocks since midnight
push dx
cmp ax,10000
jb .l1
xor dx,dx
div word [const10000]
.l1:
cmp ax,100
jb .l2
xor dx,dx
div word [const100]
.l2:
cmp ax,10
jb .l3
xor dx,dx
div word [const10]
.l3:
pop dx
ret