Reputation: 189
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
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
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