【问题标题】:convert decimal to ternary (base 3) in assembly在汇编中将十进制转换为三进制(基数 3)
【发布时间】: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 进行输出,为什么不使用sscanfstrtol 进行输入呢? strtol 可能比所有疯狂的小写和大写单独分支更有效。 (并且它会将结果累积到一个寄存器中,并且绝对不会通过执行字节添加和双字移位而导致存储转发停止。)

标签: assembly hex decimal nasm


【解决方案1】:

嗯...“十进制”、“十六进制”、“三进制”等是在文本中表示数字的方式。您已经将具有十六进制表示的数字的字符串转换为数字 - 此时没有任何真正的“十进制”。您想将您的数字除以 3,但您并没有真正将余数“添加”到任何东西,您将数字转换为代表该数字的字符(添加“0”)并将其放入缓冲区中。像往常一样,我们以“错误”的顺序得到剩余部分——在缓冲区中“向后”工作,或者以其他方式反转它们。不要忘记你想要一个以零结尾的字符串!您的 printf 格式字符串需要一个字符串,而不是整数。如果您有将数字转换为十进制表示的例程,只需将 10 更改为 3 即可。

【讨论】:

    猜你喜欢
    • 2012-06-02
    • 2014-05-24
    • 2014-07-20
    • 2016-10-16
    • 2015-06-02
    • 2015-02-04
    • 1970-01-01
    • 2016-08-21
    • 2019-05-16
    相关资源
    最近更新 更多