我的代码应该检查一个变量是奇数位还是偶数位,如果是偶数位,则将打开的位数右移,如果是奇数位,则将打开的位数左移。
这是我的代码:
IDEAL
MODEL small
STACK 100h
DATASEG
TAV db 00001001b
t_copy db 00001001b
CODESEG
start:
xor cx,cx
mov cx,8
xor al,al
L1:
shr [t_copy],1
jnc nc
inc al
nc:
dec cx
jnz L1
mov cl,al
and al,00000001h
cmp al,0h
jz even_
jnz odd
odd:
shl [TAV],cl
jmp exit
even_:
shr [TAV],cl
exit:
mov ax, 4c00h
int 21h
END start
当我运行代码的时候,它没有移动,也没有改变变量的值。我认为它改变了变量的值,作为内存中的索引。你知道我怎么修复它吗?
2条答案
按热度按时间w51jfk4q1#
当您运行TASM为您创建的.EXE时,执行从代码段中的 start 标签开始,并且CS段寄存器指向它。为了您的程序正常运行,类似地,DS段寄存器应该指向您程序的数据段。遗憾的是,默认情况下并非如此,因为DS指向程序段前缀PSP。您必须使用以下代码自己设置DS:
如果您选择
MODEL tiny
(而不是MODEL small
),则不会出现问题,因为所有4个段寄存器彼此相等。在加载寄存器之前将寄存器清零是不必要的操作。
虽然这种构造是正确的,但是如果进位被设置,则通过
adc al, 0
增加AL可以简单得多。如果进位标志被清除,则不添加任何内容,如果进位标志被设置,则添加1。检查一个值是偶数还是奇数是通过检查最低有效位来完成的,你做得很好。关键是,你不需要
cmp
,因为and
指令已经定义了你想用于分支的零标志。更好的是,如果你使用
test
而不是and
,你会收到相同的零标志,并且根本不修改寄存器。写test cl, 1
可以保存你使用额外的寄存器。这个
jnz
条件跳转没有任何作用。如果条件满足,执行跳转到的 odd 标签,如果条件不满足,执行 * 福尔斯通过**进入 odd 标签。你可以通过处理寄存器中的数据而不是内存中的数据来改进你的解决方案。你也不需要副本。
sd2nnvve2#
编辑:下面描述的错误实际上并不存在,我误读了代码。
很接近了,但是这里有一个小错误。当执行
and al,1
时,实际上已经修改了al
,并且原始的人口计数现在丢失了。幸运的是,有一个简单的方法可以解决这个问题,使用test al,1
代替。这会像and al,1
一样影响零标志。除了al
保持与test
之前的相同。因此,请尝试以下方法,看看是否有帮助: