首页 > 解决方案 > 创建一个“显示” ax 中的位的循环。“显示”一词意味着将这些位放入另一个寄存器。另一个寄存器中的值为 0 或 1

问题描述

汇编语言编程

在 ax 中存储一个值。创建一个“显示” ax 中的位的循环。“显示”一词意味着将这些位放入另一个寄存器。另一个寄存器中的值只能是 0 或 1。

我正在这样做,但我不知道我这样做是否正确。请帮忙。

.data 

x:
     .word 0b00101

.text                       

.globl _start                
                            

_start:  

     movw x, %ax
loop:
     
     cmp %ax, %bx
     
     je done
     
     andw 0b1000000000000000, %ax
     
     shl $1, %ax
     
     jmp loop
     
done:
     nop

标签: assemblyx86-16

解决方案


请使用SHLAND仅供参考

这种情况的问题是我们无法知道您还可以使用哪些其他指令。您自己的示例已经使用MOV, CMP, JE, JMP, 甚至NOP
因为该任务要求一个具有精确 16 次迭代的循环,所以很明显只使用SHLand是不可能的AND。我们至少需要一个条件跳转并使用一个独立的迭代计数器。

基本思想总是SHL将它移出的位放在进位标志中。从那里,像这样的指令ADC可以拿起它并产生结果BX=1

; IN (ax)
  mov  cx, 16
again:
  xor  bx, bx   ; BX=0
  shl  ax, 1    ; -> CF
  adc  bx, bx   ; BX=[0,1]
  loop again

现在我将删除您自己没有使用的那些XORADC和指令。LOOP此示例仅使用MOVSHLJNC

; IN (ax)
  mov  cx, 1
again:
  mov  bx, 0
  shl  ax, 1
  jnc  cont
  mov  bx, 1
cont:
  shl  cx, 1    ; Produces CF=1 after 16 iterations
  jnc  again

如果 in 中的值AX设置了最低位(如您的示例中的 0b00101),我们可以不使用独立迭代计数器。

; IN (ax)
again:
  mov  bx, 0
  shl  ax, 1
  jnc  cont     \
  mov  bx, 1    | These don't change flags
cont:           /
  jnz  again    ; Still based on the flags from `shl ax, 1`

如果你在一个AX没有设置最低位的值上使用这个片段会发生什么,那就是循环将少于 16 次迭代!


如果你有AND至少使用一次指令的冲动,你可以用它来清除BX寄存器:

; IN (ax)
  mov  cx, 1
again:
  and  bx, 0    ; ANDing BX with zero produces BX=0
  shl  ax, 1    ; -> CF now has the bit that was shifted out at the high end of AX
  jnc  cont     ; That bit was 0, so BX=0 is fine
  mov  bx, 1    ; Else make BX=1
cont:
  shl  cx, 1    ; Produces carry after 16 iterations
  jnc  again

在连续迭代CX中将保持 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 0
当值最终变为 0 时,CF 将被设置因为将值(65536)加倍的真实结果不再适合 16 位寄存器。


推荐阅读