我正在研究64位汇编代码(yasm),试图输出任意大的十进制值,以便它们正确读取,而不是像古怪或单个数字。我环顾四周,但似乎无法在线找到合适的解决方案。我的代码当前输出一个2位十进制数字(输出商,除以10时的输出余数)。对于较大的值,我正在考虑一个do-while循环结构的线路,该结构将重复除以10并输出余数而其余部分不为零。这种方法的问题在于它会反过来输出结果,为代码增加了额外的复杂性,试图扭转这种情况。有谁知道一个有效的解决方案?我看了一下aaa,aam等,但我不完全了解它们的工作方式,并怀疑这些只适用于32位操作。
代码结构如下:
section .data
nl db "",2,0
nlf db "",10,0
input db '',2,0
fact dq 1
y db 10
store dq 0
rem dq 0
quot dq 0
check dq 0
section .text
global _start
_start:
; reading input value
mov rax, 0 ; system read
mov rdi, 0 ; STD IN
mov rsi, input ; address first byte in output
mov rdx, 1 ; load length into rdx
syscall
; reading newline
mov rax, 0 ; system read
mov rdi, 0 ; STD IN
mov rsi, nl ; address first byte in output
mov rdx, 1 ; load length into rdx
syscall
mov rbx, [input] ; for calculating factorial
sub rbx, '0'
call calc_fact
call de_ASCII_fy
;add rax, 30h
mov rax, 1
mov rdi, 1
mov rsi, nlf
mov rdx, 1
syscall
; exit
xor rdi, rdi
push 0x3c
pop rax
syscall
calc_fact:
cmp bl, 1
jg do_calculation
mov rax, 1
ret
do_calculation:
dec bl
call calc_fact
inc bl
mul bl
ret
de_ASCII_fy:
mov [fact], rax
movzx rax, byte [fact]
cmp rax, 0
je decimal_loop
movzx rbx, byte [y]
xor rdx, rdx
div rbx
xor rcx, rcx
mov rcx, rdx ; store remainder
add rax, '0'
add rdx, '0'
mov [rem], rdx
mov [quot], rax
cmp rcx, 0
jnz full_print
mov rax, 1 ; system write
mov rdi, 1
mov rsi, rem
mov rdx, 1
syscall
ret
full_print:
mov rax, 1 ; system write
mov rdi, 1
mov rsi, quot
mov rdx, 1
syscall
mov rax, 1 ; system write
mov rdi, 1
mov rsi, rem
mov rdx, 1
syscall
jmp endif
endif:ret
decimal_loop:
ret
我正在计算一个阶乘值,试图显示4的输出!作为24和5!现在,此刻,我只能显示两个十进制值(由于某种原因,full_print条件的第一部分被跳过,所以3!打印为06而不是6),但24正确打印。我一直在绞尽脑汁想要打印出一个3位十进制值的简单方法,但它开始变得非常混乱条件。
答案 0 :(得分:2)
看一下这个例子:
global _start
section .bss
decimal resb 32
section .data
number dq 10000000000000000000
lf db 10
section .text
_start:
mov rdi, decimal
mov rsi, [number]
call IntegerToDecimal
mov eax, 1 ; sys_write
mov edi, 1 ; STDOUT
mov rsi, decimal ; String address
mov edx, 32 ; Max. string length
syscall
mov eax, 1 ; sys_write
mov edi, 1 ; STDOUT
mov rsi, lf ; Line Feed address
mov edx, 1 ; Max. string length
syscall
mov eax, 60 ; sys_exit
xor edi, edi ; return 0 (success)
syscall
IntegerToDecimal:
mov rax, rsi
mov ebx, 10 ; Divisor
xor ecx, ecx ; RCX=0 (Anzahl der Ziffern)
.Loop_1:
xor edx, edx
div rbx ; RDX:RAX / RBX = RAX Remainder RDX
push dx ; LIFO
add cl, 1
or rax, rax ; RAX == 0?
jnz .Loop_1 ; no: once more
.Loop_2:
pop ax ; Get back pushed digits
or al, 00110000b ; Convert to ASCII
mov [rdi], al ; Store character
add rdi, 1 ; Increment target address
loop .Loop_2 ; Until there are no digits left
mov byte [rdi], 0 ; ASCIIZ-null-terminator
ret
BTW:如果我知道操作系统(Windows或Linux)和装配风格(Nasm或Gas),你昨天就得到了这个例子。 ; - )