多次计数“操作码和操作数的无效组合”错误

问题描述 投票:0回答:1

我编写了一个汇编程序,使用冒泡排序对数组进行排序。我收到错误。
这是完整的代码:

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
assembly nasm x86-16 bubble-sort dosbox
1个回答
0
投票

此错误仅意味着最左边的操作数(目标)的大小不等于最右边的操作数(源)的大小。

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
© www.soinside.com 2019 - 2024. All rights reserved.