【发布时间】:2022-12-10 08:04:14
【问题描述】:
我的代码应该得到 2 个具有相同长度 (k) 的 arr,并检查有多少对数字具有相同的索引(1 在 arr 1 中,另一个在 arr2 中)并且相反,这意味着 1 中的第一位应该是最后一个和第二个到第一个将是第二个到第一个然后继续......
总的来说,这是我的代码:
IDEAL
MODEL small
STACK 100h
DATASEG
k dw 2 ;length of arr1 and arr2
ARR1 dw 2 dup (?)
ARR2 dw 2 dup (?)
CODESEG
start:
mov ax,@data
mov ds,ax
lea si,[ARR1]
lea di,[ARR2]
mov cx,k ; cx=length of arr
xor dx,dx
mov [ARR1],1000000000000001b
mov [ARR2],1000000000000001b
mov [ARR1+1],0033h
mov [ARR2+1],0033h
xor dx,dx
L1: ; loops through every index in both arr1, and arr2
mov bx,k
sub bx,cx
push cx
mov cx,16
L2:
xor ax,ax
shr [si+bx],1
jnc nc1
inc al
nc1:
clc
shl [di+bx],1
jnc nc2
inc ah
nc2:
clc
cmp al,ah
jne end_loop2
dec cx
jnz L2
inc dx
end_loop2:
pop cx
dec cx
jnz L1
exit:
mov ax, 4c00h
int 21h
END start
我的调试器没有给我任何错误,但是当我运行代码时它不起作用,当我左移 arr 2 中的数字时它不会更改 CF 尽管它应该。
你知道为什么会这样吗?
【问题讨论】:
-
如果我理解正确的话,你是将
0x81存储到ARR2并将0x33存储到ARR2+1,对吗?然后用shr [di+bx],1按字长移动这对?请记住,x86 是小尾数法,这意味着 CPU 将您的ARR2视为0x3381,因此您不会立即看到进位标志设置。它会在大约 5 个班次后发生。如果您以其他方式存储字节,您会在移动一次后立即看到一个进位集。 -
要么是那个,要么是汇编器对你的意图感到困惑,并用
0033h中的 33 破坏了你的1000000000000001b。如果你做了mov [ARR2],8133h.,你可能会有更好的运气 -
mov [ARR1+1],0033h表示 16 位操作数大小,因为 ARR1 使用dw。但是你只使用了+1的字节偏移量,所以它与之前的单词存储重叠。在这些初始存储之后,使用调试器检查内存中的内容。 -
@PeterCordes 啊,我错过了那部分。我认为出于某种原因它们被声明为
db。是的,您需要使用 [ARR1+2] 因为数组的每个“插槽”占用两个字节。您也可以将jnc nc1 inc al替换为单个adc al, 0并获得相同的结果。我发现跳转次数较少的代码更容易调试,因此这也可能对您有所帮助。 -
@puppydrum64:是的,有很多方法可以简化或优化它,并且同意无分支代码更容易遵循,除非它需要更多的复杂性。在这里,我可能会
mov al, [si+bx]/and al, 1然后转移到那个位。或者根据 CF 使用salc或sbb al,al实现 0 或 -1。 (这本身有点棘手,但是一旦你学会了就可以使用它。sbb ah,ah可以获得高位。)或者只是 shr /adc al, 0/ shl /sbb al, 0/jz equal_bits而不是具体化单独的布尔值进行比较。