操作或指令的参数具有非法大小 8086 子例程
argument to operation or instruction has illegal size 8086 subroutine
我开始用汇编程序为微处理器8086编程。我试着在屏幕上画一棵树,发送一个子程序,行,列,数量(从堆栈收集),我出现的错误是
argument to operation or instruction has Illegal size
在第 21 行,即执行 push count,column,row 时。
DATOS SEGMENT
row DB 1
colum DB 39
carac DB 2AH
count DB 1
ENDS
PILA SEGMENT STACK
DB 100 DUP(?)
PILA ENDS
CODIGO SEGMENT
ASSUME CS:CODIGO , DS:DATOS,SS:PILA
INICIO :
MOV AX,DATOS
MOV DS,AX
MOV AH,00h ;Clear
MOV AL,03h
INT 10h
HACER :
PUSH count ; LINE ERROR
PUSH colum ; LINE ERROR
PUSH row ;LINE ERROR
CALL DIBUJA ; CALL PROC DIBUJA
DEC colum
ADD count,2
CMP colum ,0 ; LINE ERROR
JAE HACER
POP AX
FIN : MOV AH,4CH
INT 21H
DIBUJA PROC
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BP,SP
ADD BP ,8
MOV DH, [BP] ; ACCESS TO ROW
ADD BP,2
MOV DL,[BP] ; ACCES TO COLUMN
MOV AH,02H
INT 10H
MOV BH,0 ; PAGE
MOV AL,2AH ; CHAR * HEXADECIMAL
MOV AH,0AH
ADD BP,2 ; ACCES TO COUNT
MOV CX, [BP] ; COUNT
INT 10H
POP DX
POP CX
POP BX
POP AX
RET
DIBUJA ENDP
CODIGO ENDS
END INICIO
PUSH count ; LINE ERROR
PUSH colum ; LINE ERROR
PUSH row ;LINE ERROR
您收到 "illegal size" 错误,因为 push
指令无法处理 byte-sized 内存访问。一种解决方案是首先将字节大小的变量移动到 16 位通用寄存器的低字节,然后将其压入。高字节包含垃圾这一事实并不重要:
mov al, count
push ax
mov al, colum
push ax
mov al, row
push ax
您的程序还有一些问题:
- BIOS SetCursor 函数还需要
BH
寄存器来包含要为其设置光标的显示页面。在程序中将 mov bh,0
指令移动几行。
- DIBUJA 过程压入大量寄存器,但您忘记保留您使用的
BP
寄存器。
- 设置 BP=8 可以访问 return 地址,您可以在其中访问参数。在您的代码中,您会在 [bp+10].
处找到第一个参数(行)
每次调用该过程时,都会将一些值压入堆栈。在 returning 之后,您需要将它们从堆栈中删除,否则堆栈溢出会损害您的程序。有两种方法可以解决这个问题:
让过程通过写作为它的最后一条指令来完成:
ret 6
在调用 return 之后添加堆栈指针:
call DIBUJA
add sp, 6
在 FIN 标签之前有一个多余的 pop ax
。
当你写 cmp colum, 0
jae HACER
时,你实际上写了一个 无限循环 因为变量中的每个值 colum 将始终高于或等于零。如果您将 colum 变量视为带符号的数量并使用带符号的分支 jge HACER
(跳转到大于或等于),您可能已经摆脱了它。
把它们放在一起。
HACER:
mov al, count
push ax
mov al, colum
push ax
mov al, row
push ax
CALL DIBUJA
inc row ; See final note!
DEC colum
ADD count, 2
CMP colum, 16 ; See final note!
JAE HACER
FIN:
MOV AH,4Ch
INT 21h
DIBUJA PROC
PUSH AX
PUSH BX
PUSH CX
PUSH DX
push bp
MOV BP, SP
MOV DH, [BP+12] ; ROW
MOV DL, [BP+14] ; COLUMN
MOV BH, 0 ; PAGE
MOV AH, 02h
INT 10h
MOV CX, [BP+16] ; COUNT
MOV AX, 0A2Ah ; "*"
INT 10h
pop bp
POP DX
POP CX
POP BX
POP AX
RET 6 ; +6 to remove the 3 words that were pushed as arguments
DIBUJA ENDP
最后一点。
要在 80x25 文本屏幕上获得下降树形状,您应该
- 当 colum 达到 16 时停止主循环。低至 0 将用垃圾填满屏幕!
- 增加 行 因为现在所有内容都显示在第 1 行。
我开始用汇编程序为微处理器8086编程。我试着在屏幕上画一棵树,发送一个子程序,行,列,数量(从堆栈收集),我出现的错误是
argument to operation or instruction has Illegal size
在第 21 行,即执行 push count,column,row 时。
DATOS SEGMENT
row DB 1
colum DB 39
carac DB 2AH
count DB 1
ENDS
PILA SEGMENT STACK
DB 100 DUP(?)
PILA ENDS
CODIGO SEGMENT
ASSUME CS:CODIGO , DS:DATOS,SS:PILA
INICIO :
MOV AX,DATOS
MOV DS,AX
MOV AH,00h ;Clear
MOV AL,03h
INT 10h
HACER :
PUSH count ; LINE ERROR
PUSH colum ; LINE ERROR
PUSH row ;LINE ERROR
CALL DIBUJA ; CALL PROC DIBUJA
DEC colum
ADD count,2
CMP colum ,0 ; LINE ERROR
JAE HACER
POP AX
FIN : MOV AH,4CH
INT 21H
DIBUJA PROC
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BP,SP
ADD BP ,8
MOV DH, [BP] ; ACCESS TO ROW
ADD BP,2
MOV DL,[BP] ; ACCES TO COLUMN
MOV AH,02H
INT 10H
MOV BH,0 ; PAGE
MOV AL,2AH ; CHAR * HEXADECIMAL
MOV AH,0AH
ADD BP,2 ; ACCES TO COUNT
MOV CX, [BP] ; COUNT
INT 10H
POP DX
POP CX
POP BX
POP AX
RET
DIBUJA ENDP
CODIGO ENDS
END INICIO
PUSH count ; LINE ERROR PUSH colum ; LINE ERROR PUSH row ;LINE ERROR
您收到 "illegal size" 错误,因为 push
指令无法处理 byte-sized 内存访问。一种解决方案是首先将字节大小的变量移动到 16 位通用寄存器的低字节,然后将其压入。高字节包含垃圾这一事实并不重要:
mov al, count
push ax
mov al, colum
push ax
mov al, row
push ax
您的程序还有一些问题:
- BIOS SetCursor 函数还需要
BH
寄存器来包含要为其设置光标的显示页面。在程序中将mov bh,0
指令移动几行。 - DIBUJA 过程压入大量寄存器,但您忘记保留您使用的
BP
寄存器。 - 设置 BP=8 可以访问 return 地址,您可以在其中访问参数。在您的代码中,您会在 [bp+10]. 处找到第一个参数(行)
每次调用该过程时,都会将一些值压入堆栈。在 returning 之后,您需要将它们从堆栈中删除,否则堆栈溢出会损害您的程序。有两种方法可以解决这个问题:
让过程通过写作为它的最后一条指令来完成:
ret 6
在调用 return 之后添加堆栈指针:
call DIBUJA add sp, 6
在 FIN 标签之前有一个多余的
pop ax
。当你写
cmp colum, 0
jae HACER
时,你实际上写了一个 无限循环 因为变量中的每个值 colum 将始终高于或等于零。如果您将 colum 变量视为带符号的数量并使用带符号的分支jge HACER
(跳转到大于或等于),您可能已经摆脱了它。
把它们放在一起。
HACER:
mov al, count
push ax
mov al, colum
push ax
mov al, row
push ax
CALL DIBUJA
inc row ; See final note!
DEC colum
ADD count, 2
CMP colum, 16 ; See final note!
JAE HACER
FIN:
MOV AH,4Ch
INT 21h
DIBUJA PROC
PUSH AX
PUSH BX
PUSH CX
PUSH DX
push bp
MOV BP, SP
MOV DH, [BP+12] ; ROW
MOV DL, [BP+14] ; COLUMN
MOV BH, 0 ; PAGE
MOV AH, 02h
INT 10h
MOV CX, [BP+16] ; COUNT
MOV AX, 0A2Ah ; "*"
INT 10h
pop bp
POP DX
POP CX
POP BX
POP AX
RET 6 ; +6 to remove the 3 words that were pushed as arguments
DIBUJA ENDP
最后一点。
要在 80x25 文本屏幕上获得下降树形状,您应该
- 当 colum 达到 16 时停止主循环。低至 0 将用垃圾填满屏幕!
- 增加 行 因为现在所有内容都显示在第 1 行。