【问题标题】:Coverting String Decimal to Binary and Hexa in Assembly 8086在汇编 8086 中将字符串十进制转换为二进制和十六进制
【发布时间】:2012-04-02 21:38:29
【问题描述】:

我正在尝试将使用此代码读取的字符串转换为二进制和十六进制。

READ_STRING:
    MOV DX, offset buffer
    MOV AH, 0Ah
    INT 21h
    MOV SI, 1d
    MOV AX, 0
    XOR CX, CX
    MOV CL, buffer[SI]
    INC SI

LOOP_1:
    MOV DX, 10
    MUL DX
    MOV DL, buffer[SI]
    SUB DL, 30h
    MOV DH, 0
    ADD AX, DX
    INC SI
    LOOP LOOP_1

    RET

到目前为止,我有这个二进制输出代码,但它总是打印“1001”(十进制的 9):

NEXT:

    XOR AX, AX
    XOR BX, BX
    XOR CX, CX
    MOV CL, 2
    MOV AL, byte ptr[nombre]
    MOV DI, offset binaire

; DIV : divide AX by CL. Remainder in AH and result in AL

LOOP:
    DIV CL ; remainder in AH, quotient in AL
    ADD AH, '0' ;  0 -> '0' , 1 -> '1'
    MOV [DI], AH ; Saves the remainder in the array
    INC DI
    MOV AH, 0 ; reset AH for next division
    CMP AL, 0 ; if result is 0, end
    JNE LOOP

;Prints the binary number               
    MOV DX, offset binaire
    CALL WRITE_STRING

谢谢!如果您还需要什么,尽管问。

【问题讨论】:

  • 不要尝试直接在汇编程序中编写复杂的算法。先用高级语言开发算法,再翻译。
  • ... 或让编译器为您翻译。
  • 如果你要学习汇编程序,不要学习 8086、80x86、MIPS、ARM - 任何东西,除了 16 位 DOS 808x ;)。很好的参考,如果你有兴趣:savannah.nongnu.org/projects/pgubook
  • @Carl 我该怎么做?它会与 MASM 兼容吗?
  • 我猜想获得一个 16 位 DOS 编译器 - 通常您需要稍微调整反汇编器的输出以使其与您的汇编器一起工作,但这通常并不可怕。

标签: assembly binary masm x86-16


【解决方案1】:

在担心是否可以将值显示为二进制或十六进制之前;检查以确保您的代码正确地将用户的输入转换为整数(例如使用调试器)。

对于二进制,考虑这样的事情:

    mov bx,ax              ;bx = the value to display as binary
    mov cx,16              ;cx = number of bits to display
    mov di,offset binaire  ;es:di = address to store string

.nextBit:
    xor ax,ax              ;al = 0
    add bx,bx              ;bx = value * 2; carry flag = overflow
    adc al,0               ;al = '0' or '1'
    stosb                  ;Add new character to string
    loop .nextBit
    mov byte [di],0        ;Terminate the string (ASCIIZ?)

    mov dx, offset binaire
    call WRITE_STRING

对于十六进制,基本思路相同,只是需要提取最高4位:

    mov bx,ax              ;bx = the value to display as binary
    mov cx,4               ;cx = number of nibbles to display
    mov di,offset binaire  ;es:di = address to store string

.nextNibble:
    mov ax,bx              ;ax = value
    shr ax,12              ;ax = highest 4 bits of value
    shl bx,4               ;bx = value << 4
    add al,'0'
    cmp al,'9'
    jbe .gotChar
    add al,'A' - '9'
.gotChar:
    stosb                  ;Add new character to string
    loop .nextBit
    mov byte [di],0        ;Terminate the string (ASCIIZ?)

    mov dx, offset binaire
    call WRITE_STRING

注意 1:我没有测试过上面的任何代码,而且我通常使用 NASM(不是 MASM),所以它可能无法“按原样”组装。

注意 2:上面的示例代码故意简单。为了提高性能,您可以改用查找表做得更好。

注意 3:这些不是复杂的算法,您不需要先搞砸高级语言(除非您可能不了解二进制/十六进制转换背后的理论/数学)。此外,在一种语言中看起来很优雅的算法在另一种语言中可能是一团糟(例如,您无法在 C 中以简单/干净的方式检测溢出,因此上述用于二进制转换的方法不会很明显或优雅在 C 中;而另一种在 C 中优雅的方法可能在汇编中很糟糕)。

【讨论】:

  • 更高效:rol bx, 4 这样您就可以复制和遮罩,而无需再换班。
  • 我想你想要adc al, '0' 而不是adc al, 0。 (或mov ax, '0' 而不是异或零)。就目前而言,您的循环存储的是 uint8_t 01 字节,而不是代表它们的 ASCII 数字。
猜你喜欢
  • 2013-11-24
  • 1970-01-01
  • 2012-06-02
  • 2022-11-14
  • 2014-03-24
  • 1970-01-01
  • 1970-01-01
  • 2015-06-02
  • 2019-07-27
相关资源
最近更新 更多