Can't assign a variable to the desired memory location

83 Views Asked by At

I'm new to assembly. I'm trying to move some numbers into the memory locatons starting from 0800:0010 but couldn't figure it out.
Here's the code:

.data    
    NUM0 DB 00H
    NUM1 DB 22H
    NUM2 DB 00H
    NUM3 DB 35H
    NUM4 DB 71H
    NUM5 DB 03H
.code            
    MOV AX, 0800H
    MOV DS, AX
    
    MOV AX, 0010H
    MOV ES, AX
    
    MOV DS:[0010], NUM1
    MOV DS:[0011], NUM2
    MOV DS:[0012], NUM3
    MOV DS:[0013], NUM4
    MOV DS:[0014], NUM5

The code gives an error:

(15) wrong parameters: MOV [0000], NUM1

So, I tried an alternative code:

.data    
    NUM0 DB 00H
    NUM1 DB 22H
    NUM2 DB 00H
    NUM3 DB 35H
    NUM4 DB 71H
    NUM5 DB 03H
.code            
    MOV AX, 0800H
    MOV DS, AX
    
    MOV AX, 0010H
    MOV ES, AX
    
    MOV AL, NUM1
    MOV DS:[0010], AL
    MOV AL, NUM2
    MOV DS:[0011], AL
    MOV AL, NUM3
    MOV DS:[0012], AL
    MOV AL, NUM4
    MOV DS:[0013], AL
    MOV AL, NUM5
    MOV DS:[0014], AL

This does not give any error but my desired memory location, 0800:0010 is empty. Also, even though NUM0 is useless, if I don't include it, the NUM1 is changed into 57H. When I include it, the problem seems to go away.
Also, it looks like the DS register seems to start at 0100 then go to 0000 after the line MOV DS, AX.

1

There are 1 best solutions below

4
vitsoft On

MOV AL, NUM1 in most assemblers tries to load the offset of the byte labeled NUM1 (which is 1). If you want to load the contents of this byte, it's always better to write MOV AL,[NUM1]. Such instruction loads register AL from the memory labeled NUM1, and uses default segment register DS for memory addressing, because no segment override was specified. Alas, your register DS is not initialized to point at .data segment where NUM1 resides. Try another alternative:

.data    
    NUM0 DB 00H
    NUM1 DB 22H
    NUM2 DB 00H
    NUM3 DB 35H
    NUM4 DB 71H
    NUM5 DB 03H
.code            
    MOV AX, .data ; or whichever syntax emu8086 supports
    MOV DS, AX    ; Source segment address.
    
    MOV AX, 0800H 
    MOV ES, AX    ; Destination segment address.
    
    MOV AL, [NUM1]
    MOV ES:[0010H], AL
    MOV AL, [NUM2]
    MOV ES:[0011H], AL
    MOV AL, [NUM3]
    MOV ES:[0012H], AL
    MOV AL, [NUM4]
    MOV ES:[0013H], AL
    MOV AL, [NUM5]
    MOV ES:[0014H], AL

Or, when the NUM* values are known at write-time, you can use their immediate values:

.code            
        MOV AX, 0800H 
        MOV DS,AX
        MOV BYTE [0010H],22H ; NUM1
        MOV BYTE [0011H],00H ; NUM2
        MOV BYTE [0012H],35H ; NUM3
        MOV BYTE [0013H],71H ; NUM4
        MOV BYTE [0014H],03H ; NUM5

Another alternative is mem2mem copy using MOVSB:

.data    
    NUM0 DB 00H
    NUM1 DB 22H
    NUM2 DB 00H
    NUM3 DB 35H
    NUM4 DB 71H
    NUM5 DB 03H
.code            
    MOV AX, .data ; or whichever syntax emu8086 supports
    MOV DS, AX    ; Source segment address.
    MOV AX, 0800H 
    MOV ES, AX    ; Destination segment address.
    MOV SI,OFFSET NUM1 ; Source offset.
    MOV DI,0010H  ; Destination offset.
    MOV CX,5      ; Number of copied bytes.
    CLD           ; Direction of transfer.
    REP MOVSB     ; Copy CX bytes from DS:SI to ES:DI.