【发布时间】:2014-05-04 15:11:16
【问题描述】:
我正在尝试编写一个程序,它将以十六进制表示的字符串转换为以三进制(基数 3)表示的字符串。到目前为止,我已成功将输入字符串转换为十进制,但现在我需要将其转换为三进制,我真的不知道如何在汇编(nasm)中编写它。 我只知道我需要将十进制数除以 3 并将提醒添加到最终答案中。
这是目前为止的代码:
section .rodata
LC0:
DB "The result is: %d", 10, 0 ; Format string
section .bss
LC1:
RESB 32
section .text
align 16
global my_func
extern printf
my_func:
push ebp
mov ebp, esp ; Entry code - set up ebp and esp
pusha ; Save registers
mov ecx, dword [ebp+8] ; Get argument (pointer to string)
; Your code should be here...
mov dword [LC1], 0 ; initialize answer
loop:
mov al, byte [ecx]
; if al == \n, skip it
cmp al, 10
je next
shl dword[LC1], 4 ; multiply by 16 each digit we add
; if al >= 'a'
cmp al, 'a'
jge ge_a
; if al >= 'A'
cmp al, 'A'
jge ge_A
; if al >= '0'
cmp al, '0'
jge ge_0
; default
; do nothing
jmp next
ge_a: ; a <= al
; if al <= 'f'
cmp al, 'f'
jle a_f
; else
jmp next
ge_A: ; A <= al
; if al <= 'F'
cmp al, 'F'
jle A_F
; else
jmp next
ge_0: ; 0 <= al
; if al <= '9'
cmp al, '9'
jle n0_9
; else
jmp next
a_f: ; [a, f]
sub al, 'a'
add al, 10
add byte[LC1], al
jmp next
A_F: ; [A, F]
sub al, 'A'
add al, 10
add byte[LC1], al
jmp next
n0_9: ; [0, 9]
sub al, '0'
add byte[LC1], al
jmp next
next:
inc ecx ; increment pointer
cmp byte [ecx], 0 ; check if byte pointed to is zero
jnz loop ; keep looping until it is null terminated
push dword[LC1] ; Call printf with 2 arguments: pointer to str
push LC0 ; and pointer to format string.
call printf
add esp, 8 ; Clean up stack after call
popa ; Restore registers
mov esp, ebp ; Function exit code
pop ebp
ret
【问题讨论】:
-
与转换为十进制的方式相同:重复除/模数以按顺序获得数字。 stackoverflow.com/questions/13166064/…
-
另外,如果您要使用
printf进行输出,为什么不使用sscanf或strtol进行输入呢?strtol可能比所有疯狂的小写和大写单独分支更有效。 (并且它会将结果累积到一个寄存器中,并且绝对不会通过执行字节添加和双字移位而导致存储转发停止。)