问题

1

写汇编代码时发现一个error ,如上图,指令或指示有错,代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
; 定义延时宏,循环显示00~99,数字之间用延时宏进行延时
DATAS SEGMENT
; 此处输入数据段代码

DATAS ENDS

STACKS SEGMENT
; 此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    ; 此处输入代码段代码
    ; 宏定义
delay MACRO time
    local p1,p2
    pusha
    mov dx,time
p1:
    mov cx,0ff00h
p2:
    loop p2
    dec dx
    jnz p1
    popa
ENDM
lop:
   mov ch,0
hi:
    mov cl,0
lo:
    mov dl,ch
    add dl,30h
    mov ah,02h
    int 21h

    mov dl,cl
    add dl,30h
    mov ah,02h
    int 21h

    mov dl,32  ; 输出空格ascii=32
    mov ah,02h
    int 21h

    delay 5   

    inc cl
    cmp cl,9
    jle lo

    inc ch
    cmp ch,9
    jle hi
    jmp lop
fin:
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

宏使用出错,检查宏代码,找了好久也没有找到哪里出问题了 😔

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
MASM generates the following error message if the PUSHA or POPA instructions are
used without a prior .186, .286, or .386 directive:

  A2105: Expected: instruction, directive, or label

This error does not clearly indicate exactly what the problem is. By default, the
Macro Assembler generates code for the 8086 processor, for which these
instructions have not been implemented.

Page 302 of the "Macro Assembler 5.1 Programmer's Guide" states that these
instructions are implemented only for the 80186, 80286, and 80386 processors.

If you have an 8086-based computer, you will have to push and pop the registers
individually, using PUSH and POP. If you have a 80186, 80286, or 80386-based
computer, add the appropriate directive to the code.

PUSHAPOPA 用于80186,80286,80386,以后的处理器。

学校里发的 LJ 教材中80x86指令集中就有 PUSHAPOPA ,好多代码也用这两个指令,额,又一次让我明白尽信书不如无书。

改正

方法一:删掉 PUSHAPOPA ,将用到的寄存器依次 push,而后逐个 pop

方法二:在程序开头加一行 .186

参考资料

1.https://jeffpar.github.io/kbarchive/kb/040/Q40192/

2.https://en.wikipedia.org/wiki/X86_instruction_listings#Original_8086/8088_instructions