操作或指令的参数具有非法大小的8086子程序

时间:2017-01-11 07:19:17

标签: assembly x86-16

我开始使用汇编程序为微处理器8086编程。我尝试在屏幕上绘制一个树,发送子程序,行,列,数量(从堆栈中收集),我出现的错误是

  

操作或指令的参数具有非法大小

在第21行,即执行推送计数,列,行时。

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

1 个答案:

答案 0 :(得分:2)

PUSH   count ; LINE ERROR
PUSH   colum ; LINE ERROR
PUSH   row   ;LINE ERROR

您收到“非法大小”错误,因为push指令无法处理字节大小的内存访问。解决方案是首先在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可以访问返回地址,您可以在其中访问参数。在您的代码中,您将在[bp + 10]找到第一个arg()。
  • 每次调用该过程时,都会在堆栈上推送一些值。返回后,您需要从堆栈中删除这些,否则堆栈溢出将损害您的程序。有两种方法可以解决这个问题:

    • 让程序通过写作最后一条指令来完成:

      ret 6
      
    • 从通话中返回后添加stackpointer:

      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行上。