编辑:
我没有预料到这个问题会如此迅速地引起关注。根据我已经收到的答案,似乎我漏掉了一个重要的信息。该模式没有固定数量的位。有些字母可能具有更多或更少的位。例如,B有5位,但C可能使用多达6位,但没有任何一个超过一个字节。我在我的问题中包含了“A”位模式的示例,每行使用7位。请参见问题底部的编辑。
我是组合语言的新手。我有一个位模式,对应于字母的文本表示。每个1代表$(或任何符号),每个0代表空格。例如:
$$$$ 11110
$ $ 10001
$ $ 10001
$$$$ 11110
$ $ 10001
$ $ 10001
$$$$ 11110
$ 0001000
$ $ 0010100
$$$$$ 0111110
$ $ 1000001
我编写了一个汇编程序,它可以读取每个模式并根据读取到的1或0打印正确的符号。为了确定它是1还是0,我将寄存器与1进行AND运算,然后将位向右移,位移量等于每行中的位数,然后比较结果:
请注意,每行的位都存储在单独的2字节单词的底部,我将其加载到8位寄存器中。
patternb: dw 011110b,010001b,010001b,011110b,010001b,010001b,011110b
rowloop:
mov bl,[patternb+si] ;iterate through each element in binary array
patternloop:
mov bh,bl ;move bit pattern into register so that we can change it
and bh,1 ;AND register to find set bits and store back in register
shr bl,1 ;SHIFT original bit pettern right
cmp bh,1 ;check if bit is set or not (1=set, else 0)
je writesym ;if set, write symbol
jne writeblank ;if not set, write space
问题在于AND操作的方式。很明显,它从最低有效位(least significant bit)开始,并且随着右移而打印比特位,但这会导致字母“反向”打印的问题。例如:
####
# #
# #
####
# #
# #
####
我已经尝试了一些位操作,但都没有成功。我也尝试将位模式移动和旋转以对应正确的打印方式,但由于不是每行都需要这样操作,所以这种方法不适用于每行。例如,第二行将在无需先进行操作的情况下正确打印。我对字母A-E采用了相同的位模式技术。
理想情况下,我希望能从最高有效位开始进行比较,这样应该会按正确顺序打印,但我不确定如何操纵位以实现此目的。
编辑: 根据Peter Duniho的答案,我想分享一些我尝试过的内容: 我尝试将模式与10000b进行AND运算,然后ROL结果以得到
00001b
的答案,然后向左移动位。然后比较结果以查看应打印哪个符号。但由于位模式并不总是固定的,所以这也不是一个解决方案。 mov bh,bl ;move bit pattern into register so that we can change it
and bh,10000b ;AND register to find set bits and store back in register
rol bh,1 ;rol result to obtain 00001b
shl bl,1 ;SHIFT original bit pettern right
cmp bh,1 ;check if bit is set or not (1=set, else 0)
je writesym ;if set, write symbol
jne writeblank ;if not set, write space
目前最接近解决这个问题的方法(在 Peter Duniho 的答案帮助下),是将我的位数组存储为完整的 8 位形式(即使用 011110000b
等,而不是 011110b
,否则汇编器会隐式地将它存储为 00011101
,正如 Martin Rosenau 所述,我们不想要这样),并用完整的 10000000b
进行 AND 操作(因为我们最多使用 8 位,这样可以检查 MSB),而不是像我之前尝试的那样用 1(000000001b
)进行 AND 操作,然后使用上面的 ROL 和比较方法(或者只将其与 10000000b
进行比较)。循环总共运行了 7 次(因为每个字母都有 7 条线路/位模式,除了 A 只有 4 条,所以 A 打印不正确,但这是我可以通过一些条件来解决的问题)。该程序现在能够正确工作和打印。这是我使用的代码:
mov bh,bl ;move bit pattern into register so that we can change it
and bh,10000000b ;AND register to find set bits and store back in register
rol bh,1 ;shift MSB to LSB to compare (or could just compare with 10000000b instead)
shl bl,1 ;SHIFT original bit pettern left
cmp bh,1 ;check if bit is set or not (or use cmp bh,10000000b and omit rol above)
je writesym ;if set, write symbol
jne writeblank ;if not set, write space
我已将Peter的解决方案标记为答案,因为它指引了我解决这个问题的正确方向。但正如他所提到的,有许多种方法可以解决这个问题(正如发布的不同解决方案所示),而他的解决方案恰好是我实现自己代码中最容易的方法,这也是他的目的。
Martin Rosenau的回答也很有见地,尤其是优化方面。我会在有更多时间时尝试实现这些优化,并更新上述解决方案。
add bl,bl / jc writesym
,否则继续执行或跳转到writeblank。 - Peter Cordes