我编写了一个汇编程序,使用冒泡排序对数组进行排序。我收到错误。
这是完整的代码:
org 100h
section .data
array db 5, 3, 7, 1, 4, 9, 2, 8, 6
array_size db 9
new_line db 0xA
comma db ','
section .bss
temp resb 1
output resb 2
section .text
start:
mov al, [array_size]
dec al
mov cl, al
bubble_sort:
xor bx, bx
outer_loop:
cmp bx, cl
jge done
xor si, si
inner_loop:
mov al, [array_size]
sub al, bl
cmp si, al
jge next_outer_loop
mov al, [array + si]
mov dl, [array + si + 1]
cmp al, dl
jle next_esi
mov [temp], al
mov [array + si], dl
mov al, [temp]
mov [array + si + 1], al
next_esi:
inc si
jmp inner_loop
next_outer_loop:
inc bx
jmp outer_loop
done:
xor si, si
print_loop:
mov al, [array + si]
add al, '0'
mov [output], al
mov ah, 09h
lea dx, [output]
int 21h
inc si
mov al, [array_size]
cmp si, al
jge print_loop
为什么 NASM 给我这些错误?
第 23 行错误:操作码和操作数的组合无效
第 31 行错误:操作码和操作数的组合无效
第 66 行错误:操作码和操作数的组合无效
相关行如下:
cmp bx, cl
cmp si, al
cmp si, al
此错误仅意味着最左边的操作数(目标)的大小不等于最右边的操作数(源)的大小。
cmp
指令(像大多数其他指令一样)无法处理这种不匹配。
在您的程序中,最简单的解决方法是声明 array_size 一个 16 位数量:
array_size dw 9
,当然还要加载到 AX!
所以这是操作数之间的不匹配,但是为什么错误消息会提到“操作码和操作数的组合无效”?
这是因为一些指令确实允许操作数之间存在这种不匹配。值得注意的是
movzx
和 movsx
指令可以接受它。例如。 movzx bx, cl
会将 CL 复制到 BL 中,并将 BH 归零。
mov [temp], al mov [array + si], dl mov al, [temp] mov [array + si + 1], al
请注意,对于交换部分,您不需要 temp 变量:
mov [array + si], dl
mov [array + si + 1], al
另请注意,使用
output resb 2
并让 print_loop 仅写入这两个字节中的第一个 (mov [output], al
),屏幕将显示大量垃圾。通过按照 DOS.PrintString 函数 09h 的要求添加 $ 字符来解决此问题。
print_loop:
mov al, [array + si]
add al, '0'
mov ah, "$"
mov [output], ax