DOS segment
.model small
.stack 100h
.data
array1 dw 1,4,6,3,7 ; since division 8 bit divisor require 16 bit dividend
.code
main proc
mov ax,@data
mov ds,ax
lea si,array1
mov cx,5
l1:
mov ax,[si]
mov bl,2
div bl
cmp ah,0
jne odd **if the remainder is not 0 means even**
resume:
inc si
loop l1
odd:
push ax **I am using stack**
jmp resume
mov cx,5
l2:
mov ax,[si]
mov bl,2
div bl
cmp ah,0
je even **if the remainder is 0 means even**
re:
inc si
loop l2
even:
push ax
jmp re
mov cx,5
l3:
pop dx
mov ah,2
int 21h
loop l3
main endp
end main我相信我的算法是正确的,但我面临的问题是除法错误。我环顾四周,当它发生在CX=0时,但是循环将如何工作呢?我很困惑。
如果有人能告诉我解决方案,我将不胜感激
发布于 2020-05-16 23:47:39
...if余数不是0表示偶数
...if余数为0表示偶数
不可能两者同时都是正确的!
第一个循环推入奇数
lea si,array1 mov cx,5 l1: mov ax,si mov bl,2 div bl cmp ah,0 jne奇数**如果余数不是0表示偶数** resume: inc si循环l1奇数:推送ax **我正在使用堆栈** jmp resume
问题是,您已经将奇怪的标签放在了结束循环的LOOP指令的正下方(当CX变为0时)。在这些push ax和jmp resume指令中,代码将错误地失效!
您需要通过传递该push ax来重新组织代码
cmp ah, 0
je Even
push ax ; This pushes an ODD number BUT DOES IT ? (1)
Even:
inc si ; This advances to the next number BUT DOES IT ? (2)
loop l1(1) AX寄存器不再保存数组中的数字,因此您需要使用push word ptr [si]将该字从数组中推入。
(2)因为数组包含单词,所以您需要使用add si, 2前进2。
第二个循环推入偶数
mov cx,5 l2: mov ax,si mov bl,2 div bl cmp ah,0 je even**如果余数为0则表示偶数** re: inc si l2 even: push ax jmp re
我在第一个循环中所说的一切也适用于这里。此外,还需要用lea si, array1初始化SI寄存器。
第三个循环打印推送的所有内容
mov cx,5
l3:
pop dx
mov ah,2
int 21h
loop l3从堆栈中弹出的是一个数字,但DOS.Printchar函数需要DL中的字符。需要进行一些转换:
pop dx
add dl, '0'程序中的一些问题源于您使用除以2来测试偶数/奇数。这使得您将数组定义为单词,并且忘记了更改inc si指令。
判断一个数字是偶数还是奇数的方法是通过查看它的最低位。您可以对其使用test指令:
array1 DB 1, 4, 6, 3, 7
...
L1:
mov al, [si]
test al, 1
jz Even
push ax ; Pushing the odd number still in the AL register
Even:
inc si
dec cx
jnz L1https://stackoverflow.com/questions/61760970
复制相似问题