BCRwar1
BCRwar1

Reputation: 189

Obtaining a variable's value in Assembly Language

Probably a stupid question, but this my first project in my Machine Organization class and I'm having some trouble. The code below is meant to display '*' in the middle of the screen from top to bottom. The line of code that wont assemble is:
MOV ES: [ numLoops * 80 * 2 + (40 * 2) ], BYTE PTR '*'

I understand why this won't assemble, but I do not know what to put in place of numLoops in order to get its value so that each time the line of code is executed it moves up a row as numLoops gets decremented. Any advice would be greatly appreciated, thank you.

MyData SEGMENT

    numLoops DB 25

MyData ENDS     

;-------------------------------------------------------------------------------
MyCode SEGMENT

        ASSUME CS:MyCode, DS:MyData   

MainProg  PROC                

    MOV     AX, MyData             
    MOV     DS, AX                 
    MOV     AX, 0B800h         
    MOV     ES, AX

    loop25: 

      CALL displayChar

      DEC numLoops                  
      CMP numLoops, 0
    JNE loop25                ;if not equal to 0, numLoops - 1 and repeat

    MOV     AH, 4Ch                
    INT     21h                   

MainProg ENDP  

displayChar  PROC 

    MOV     ES: [ numLoops * 80 * 2 + (40 * 2)  ], BYTE PTR '*' 

    RET
displayChar ENDP                 

MyCode ENDS 

Upvotes: 1

Views: 314

Answers (2)

Tyler Durden
Tyler Durden

Reputation: 11558

Do not try to modify constant memory (as was in the original question).

The number of loops should be held in a register, not in constant data. So you should have something like:

MOV CX, 25     ; number of times to loop
[do math on CX and put in DX]
MOV ES:DX, BYTE PTR '*'

As a rule you should minimize the use of segments. Due to modern computers having large amounts of memory most assembly language now uses the "flat" model in which segments are not used except for specialized purposes.

Upvotes: 1

Michael
Michael

Reputation: 58487

Use a register to calculate numLoops * 80 * 2:

  mov bx,[numLoops]
  imul bx,bx,160
  mov byte ptr es:[bx + 40*2],'*'  ; note that byte ptr goes before the memory
                                   ; operand, not the immediate operand.

There are more efficient ways of doing this (e.g. start out with 25*160 in a register and just subtract 160 from it during each iteration), but this should suffice if you just want something that works.

Upvotes: 1

Related Questions