I am converting a program from EMU8086 environment to NASM. When assembling NASM gives these errors :
system\kernel.asm:14: error: invalid combination of opcode and operands
system\kernel.asm:20: error: invalid combination of opcode and operands
system\kernel.asm:28: error: invalid combination of opcode and operands
My code is:
jmp start
;==============================
;Draws a horiz and vert line
;==============================
startaddr dw 0a000h ;start of video memory
colour db 1
;==============================
start:
mov ah,00
mov al,19
int 10h ;switch to 320x200 mode
;=============================
horiz:
mov es, startaddr ;put segment address in es *** 1st ERROR HERE!
mov di, 32000 ;row 101 (320 * 100)
add di, 75 ;column 76
mov al,colour
mov cx, 160 ;loop counter
hplot:
mov es:[di],al ;set pixel to colour *** 2nd ERROR HERE!
inc di ;move to next pixel
loop hplot
vert:
mov di, 16000 ;row 51 (320 * 50)
add di, 160 ;column 161
mov cx, 100 ;loop counter
vplot:
mov es:[di],al ; *** 3rd ERROR HERE!
add di, 320 ;mov down a pixel
loop vplot
I have marked the lines with the errors. Why doesn't this work in NASM?
The MOV instruction has a few limitations: an immediate value cannot be moved into a segment register directly (i.e. mov ds,10) segment registers cannot be copied directly (i.e. mov es,ds) a memory location cannot be copied into another memory location (i.e. mov aNumber,aDigit)
The es (Extra Segment) register is an extra segment register. 8086 programs often use this segment register to gain access to segments when it is difficult or impossible to modify the other segment registers. The ss (Stack Segment) register points at the segment containing the 8086 stack.
The register SI and DI are called index registers. These registers are usually used to process arrays or strings. SI is called source index and DI is destination index. As the name follows, SI is always pointed to the source array and DI is always pointed to the destination.
Index Registers Source Index (SI) − It is used as source index for string operations. Destination Index (DI) − It is used as destination index for string operations.
Since 0xA000 is a constant, one can define it as such and then use it as an immediate value rather than a memory operand. In order for this approach to work you need to place the constant in an intermediate register and then move it to the segment register.
You can define startaddr as a constant (not a memory address containing the segment value). You can create constants (immediate values) by using EQU. Change this line:
startaddr dw 0a000h ;start of video memory
to
startaddr EQU 0a000h ;start of video memory
Since you can't MOV an immediate value to DS, ES, and SS directly, you place the value into an intermediate register and then move it to the segment register. So this code:
mov es, startaddr ;put segment address in es
Could be:
mov ax, startaddr
mov es, ax ;put segment address in es
Note: If creating readable code, and you use the method above - I recommend renaming startaddr to STARTADDR. The convention of an all upper case identifier suggests to the reader it is a constant (immediate value) instead of a variable.
The other errors you have are related to a syntax difference between EMU8086 and NASM. These lines:
mov es:[di],al ;set pixel to colour
and
vplot:
mov es:[di],al
Need to be written with the segment inside the square brackets. They should look like this:
mov [es:di],al ;set pixel to colour
and
vplot:
mov [es:di],al
I highly recommend you read the NASM documentation about generating DOS COM and EXE programs
In NASM you have to use square brackets to retrieve the value at startaddr.
Write:
mov es, [startaddr] ;put segment address in es
Also NASM expects you to write the segment override between these brackets:
mov [es:di],al ;set pixel to colour
One additional error that NASM can't possibly detect for you is how you thought having retrieved the colour variable. You should also use [] here:
mov al, [colour]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With