【问题标题】:Converting decimal to binary in assembler在汇编程序中将十进制转换为二进制
【发布时间】:2015-02-04 19:31:13
【问题描述】:

我的第一个汇编程序需要帮助。 我必须将用户输入的值从十进制转换为二进制。 我不知道如何将值显示为小数,以及下一步该怎么做。 谁能一步一步指导我下一步该怎么做。

    .model small
    .stack 100h`

    .data
            txt1 db "Enter binary value:" ,10,13, "$"
            txt2 db "BIN: " ,10,13, "$"


    .code

        main proc
        mov ax, @data
        mov ds, ax
        ;clear screen
        mov ah,0fh
        int 10h
        mov ah,0
        int 10h
        ;show first text
        mov ah, 9
        mov dx, offset txt1
        int 21h
        call Number


        main endp


        Number proc
        mov cx,5
        xor bx,bx

        read:
        mov ah,0
        int 16h
        cmp al,'0'
        jb read
        cmp al, '9'
        ja read
        mov ah,0eh
        int 10h
        loop read
        Number endp

        mov ax, 4c00h
        int 21h

        end main

【问题讨论】:

    标签: assembly binary decimal dos x86-16


    【解决方案1】:

    我想你会没事的。

    ; Read an integer from the screen and display the int in binary format
    ; and continue until number is negative.
    again:            ; For loop
        call read_int ; take the integer from screen
        cmp eax,0     ; look if number is not negative
            JL end:       ; if less than zero program ends.
        mov ecx,32    ; for loop we set ecx to 32 ; ATTENTION we not specified type. So compiler will get error.
    
        mov ebx,eax   ; we will lost our number in eax, so I take it to ebx
    START:
        xor eax,eax   ; eax = 0
        SHL ebx,1     ; shift the top bit out of EBX into CF
        ADC eax,0     ; EAX  = EAX + CF + 0 ADD CARRY FLAG, so eax is zero we add zero. The new eax will exact value of Carry Flag which is out bit.
        call print_int ; Then we print the CF which we took the eax.
    LOOP start:   ; Loop looks ecx if not 0 it goes start.  
    call print_nl ; For next number we print a new line
    JMP again:    ; For take new number
    
        END:      ; End of the program.
    

    setc al 也可以代替adc eax,0 工作,并且在某些 CPU 上效率更高。

    【讨论】:

    • xor eax,eax 设置 CF=0。在shl 之前执行此操作。 (并使用setc al 而不是adc 以提高效率)。 Also, the LOOP instruction is slow, don't use it. 除非优化代码大小而不是速度。此外,您在循环中有mov ebx, eax。在发布之前测试您的 asm 可能会更好。
    • 另外,您没有描述您正在使用的调用约定。您似乎正在使用 Irvine32 约定,其中第一个 arg 进入 eax,返回值也是如此。这根本不是标准或广泛使用的。 (另外,这是一道 16 位的 DOS 题,虽然算法是一样的。)
    • 顺便说一句,欢迎来到 Stack Overflow。如果/当您调试此代码时,我很乐意推翻我的反对意见。它既漂亮又紧凑,并且有 cmets 描述它在做什么,并且是一个不错的答案,除了错误。通过在您的评论中包含@peter 来通知我。
    • 亲爱的@PeterCordes 感谢您的回复,当我使用 SHL 它设置 CF 时,我不在乎这种情况下的 eax 是什么。我的号码是 ebx 而不是 eax。也许我把开始标签放错了行。我将进行编辑,如果您愿意,请使用我的代码并对其进行修复并为我们分享。
    • 对,shl 向 CF 移动了一点,但随后xor eax,eaxadc eax,0 之前清除了 CF(写成setc al 会更有效)
    【解决方案2】:

    不完全清楚您要做什么。我猜“十进制到二进制”,但提示说“输入二进制值”。我认为这意味着一串“1”和“0”。我也不会要求他们提供“十进制”值 - 你会得到像“1.23”,你没有能力处理。只需向他们要一个号码。也许是“小于 65536 的数字”,这可能是(?)你想要的。

    警告!前面有未经测试的代码!

        Number proc
        mov cx,5 ; loop counter?
        xor bx,bx ; "result so far"?
    
    
        read:
        mov ah,0
        int 16h
    
    ; wanna give 'em the option to enter
    ; less than the full five digits?
        cmp al, 13 ; carriage return
        jz finis
    
        cmp al,'0'
        jb read
        cmp al, '9'
        ja read
        mov ah,0eh
        int 10h
    ; Assuming al still holds your character...
        sub al, '0' ; convert character to number
        mov ah, 0 ; make sure upper byte is clear
        imul bx, bx, 10 ; multiply "result so far" by 10
        ; jc overflow ;  ignore for now
        add bx, ax ; add in the new digit
        ; jc overflow ; ignore for now
    
        loop read
    finis:
    ; now our number is in bx
    ; it is conventional to return values in ax
        mov ax, bx
    
    overflow: ; I'm just going to ignore it
        ; spank the user?
        ; go right to exit?
        ret ; maybe endp generates this. two shouldn't hurt
        Number endp
    

    现在我猜你想打印那个数字的二进制(“1”和“0”)表示......

        Printbin proc
    ; what does "proc" do? Do you know?
        mov bx, ax
        mov cx, 16 ; 16 bits to do, right?
        mov ah, 2
     top:
        mov dl, '0'
        shl bx, 1 ; shift leftmost bit to carry flag
        adc dl, 0 ; bump the "0" up to "1", if set
        int 21h
        loop top
        ret
    
        endp ; ?
    

    我做DOS已经有一段时间了,所以可能会有严重的错误,但它可能会给你一些想法。

    【讨论】:

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