【问题标题】:EMU8086 Assembly: Output generates the total number of bits instead of The number of 0s in the outputEMU8086 汇编:输出生成总位数而不是输出中 0 的数量
【发布时间】:2021-08-25 00:03:56
【问题描述】:

任务是获取十进制的用户输入,生成 16 位的二进制,然后找出二进制输出中 0 的数量。 找出二进制文件的第一部分似乎工作正常,但我在第二部分做错了什么?它显示的是总位数而不是 0。

示例:输入:3 输出:0000000000000011 0 的数量:14

include "emu8086.inc"
.model small
.stack 100h
.data
zeroes dw ?
.code
    ;First part, user input in decimal then generating the output in Binary, 16 bits. --Works FINE

    mov ax, @data
    mov ds, ax
    
    call scan_num
    printn
    
    print "The binary is: "
    
    mov bx, 16
    
    _loop:
    shl cx, 1
    jc bin_1
    
    putc '0'
    
    dec bx
    jnz _loop
    jmp exit
    
    bin_1:
    putc '1'
    
    dec bx
    jnz _loop
    
    
    ;Second part, finding out the number of 0 bits in the binary output
    mov cx, 16
    
    up:
    rol ax, 01h
    
    inc bx
    
    jmp next
    next:
    loop up
    mov zeroes, bx
    
    mov ax, bx 
    printn
    print "The number of 0s: "
    call print_num
     
    
exit:
    mov ah, 4ch
    int 21h
    
;define
define_print_num
define_print_num_uns
define_scan_num

【问题讨论】:

  • jmp next 到 next: 是空操作;无论如何,执行都会落到下一条指令。而且您的第二部分中没有任何条件分支,也没有任何无分支读取 CF 的内容,如rol 设置的那样以这种方式进行条件增量(例如adc bx, 0)。如果您在调试器中单步执行您的代码,应该很容易看出它只将 BX 计数到 16。

标签: assembly x86-16 emu8086


【解决方案1】:

考虑一下

如果您的输入是偶数(0、2、4、...),那么显示数字二进制表示的循环将在尝试第二部分之前退出程序! jmp exit 指令的内容应该类似于 jmp SecondPart。

除了 Peter Cordes 在评论中写的内容之外,我想补充一点,如果 scan_num 给了您CX 寄存器中的数字,并且您在第一个循环中将其清除,则在第二个循环中无需处理更多内容。此外,在第二个循环中,您希望数字在AX; scan_num 是否一次将其结果传送到 2 个寄存器中???

现在解决方法

如果第一个循环还可以完成计数零的工作,为什么还要编写第二个循环?
当您可以使用可用的通用寄存器时,您不需要 zeroes(基于内存的)变量。

        ...
        call  scan_num
        printn
        print "The binary is: "
        XOR   BP, BP     ; Clear counter
        mov   bx, 16
    _loop:
        shl   cx, 1
        jc    bin_1
    bin_0:
        INC   BP         ; Found an extra zero
        putc  '0'
        dec   bx
        jnz   _loop
        JMP   DONE
    bin_1:
        putc  '1'
        dec   bx
        jnz   _loop
    DONE:
        MOV   AX, BP
        printn
        print "The number of 0s: "
        call  print_num
    exit:
        ...

我已将更改大写,以便您轻松查看差异。

【讨论】:

  • 或者,您可以只提取最高位(或旋转后的最低位)以有条件地递增,并在 add al, '0' 之后使用寄存器而不是常量来放置。但是,是的,如果你要保持分支的每一点,那是明智的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-19
  • 2016-08-17
  • 2016-09-26
  • 1970-01-01
  • 2016-05-09
相关资源
最近更新 更多