argument to operation or instruction has illegal size 8086 subroutine

房东的猫 提交于 2021-01-29 03:17:34

问题


I started programming in assembler for microprocessor 8086. I try to draw a tree on the screen, sending a subroutine, row, column, amount (collected from the stack), the error I present is

argument to operation or instruction has Illegal size

on line 21, ie when performing the 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

回答1:


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

You get an "illegal size" error because the push instruction can't deal with a byte-sized memory access. A solution is to first move the byte sized variable in the low byte of a 16-bit general register and then push that. The fact that the high byte will contain garbage is of no importance:

mov  al, count
push ax
mov  al, colum
push ax
mov  al, row
push ax

There are some more issues with your program:

  • The BIOS SetCursor function also requires the BH register to contain the display page for which you want to set the cursor. Move the mov bh,0 instruction a few lines up in your program.
  • The DIBUJA procedure pushes a lot of registers, yet you forget to preserve the BP register that you use.
  • Setting BP=8 gives access to the return address, where you want access to the arguments. In your code you'll find the 1st arg (row) at [bp+10].
  • Each time you call the procedure you push some values on the stack. Upon returning you need to remove these from the stack else a stack overflow will harm your program. There are 2 ways to solve this:

    • Have the procedure do it by writing as its last instruction:

      ret 6
      
    • Add the stackpointer after returning from the call:

      call DIBUJA
      add  sp, 6
      
  • There's a superfluous pop ax right before the FIN label.

  • When you wrote cmp colum, 0 jae HACER, you effectively wrote an infinite loop because every value in the variable colum will ALWAYS BE ABOVE OR EQUAL TO ZERO. You could have gotten away with it had you treated the colum variable a signed quantity and used the signed branch jge HACER (jump on greater or equal).


Putting it all together.

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

A final note.

To obtain a descent tree shape on the 80x25 textscreen, you should

  • stop the main loop when colum reaches 16. Going as low as 0 will fill the screen with garbage!
  • increment the row because now everything gets displayed on the row 1.


来源:https://stackoverflow.com/questions/41584877/argument-to-operation-or-instruction-has-illegal-size-8086-subroutine

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!