1

I'm very new to assembly programming, mostly just trying to learn from youtube videos and the "assembly language for x86 processors" pdf. the program is no where near completion now, but I'm already getting 3 errors I can't figure out.

  1. invalid character in file (line 1)
  2. invalid instruction operands (lines 27,46,26)
  3. Symbol type conflict (line 15)

    .model small
    .data
    message db "Please enter a for mutiplication or b for division $"
    message2 db " Enter the first number $"
    message3 db " Enter the second number $"
    message4 db " * $"
    message5 db " / $"
    message6 db " = $"
    
    .code
    main proc
    mov ax, seg message
    mov ds, ax
    mov dx, offset message
    mov ah, 9h
    int 21h
    
    mov ah, 1h ;input stored in al
    int 21h
    
    mov bl, al ; menu selection input stored in bl so al can be used freely
    
    mov ah, seg message2
    mov ds, ah
    mov dx, offset message2
    mov ah, 9h
    int 21h
    
    mov ah, 1h; input stored in al
    int 21h
    
    mov cl, al ; first number input stored in cl so al can be used freely
    
    mov dl, bl
    mov ah, 2h
    int 21h
    
    mov dl, al ;second number imput stored in dl so al can be used again
    
    sub cl, 30h ;convert characters to decimal
    sub dl, 30h
    
    mov ax, cl ;preform division
    div dl
    
    mov al, cl ;preform multiplication
    mul dl
    
    
    add cl, 30h ; convert decimal back to the characters
    add dl, 30h
    
    
    
    main endp
    
     end main
    

eventually I want to limit the range of inputs to 1-100 and I'd appreciate any tips on how to do that also, any help would be appreciated

Fifoernik
  • 9,411
  • 1
  • 18
  • 26
  • Remove the lines that try to get the segment from `message`. At the top of your code you can set _DS_ once with `mov ax, @data` `mov ds, ax`. – Michael Petch Apr 29 '17 at 05:41
  • The line `mov ax, cl` is not allowed. _CL_ is an 8 bit register and _AX_ is a 16-bit register. – Michael Petch Apr 29 '17 at 05:42
  • When I use '@data' now its giving me a new error "undefined symbol: Dgroup" on the line with the '@data'. What am i missing here? do i need to use IsDefined? – Mark Gonzalez Apr 29 '17 at 06:35
  • What are you using to assemble this? What is your linker? Almost sounds like your linker may not understand 16-bit. – Michael Petch Apr 29 '17 at 06:36
  • I'm using Microsoft visual studio i opened a win32 project with build customization set to masm – Mark Gonzalez Apr 29 '17 at 06:40
  • You can't generate 16-bit code with the assembler and linker that comes with Visual Studio. You have to obtain a version of MASM that can generate 16-bit objects and you need a 16-bit linker. – Michael Petch Apr 29 '17 at 06:43
  • well that explains a lot, do you have any suggestions of something i can use? – Mark Gonzalez Apr 29 '17 at 06:47

1 Answers1

2

I couldn't reproduce here the errors 1) and 3). Maybe they are "gone" with copying. Delete the lines in the source and type them again.

"error A2070:invalid instruction operands":

1) Lines 27 and 26:

mov ah, seg message2
mov ds, ah

A segment is a 16-bit value. You cannot load it into an 8-bit register (AH). Furthermore, you cannot copy an 8-bit register (AH) to a 16-bit register (DS). Change the lines to:

mov ax, seg message2
mov ds, ax

2) Line 46:

mov ax, cl ;preform division
div dl

You cannot copy an 8-bit register (CL) to a 16-bit-register (AX). There are special instructions to perform such a thing: MOVZX & MOVSX. The first instruction treats the 8-bit register as an unsigned integer, the second as signed integer. Change the lines to:

movzx ax, cl ;preform division
div dl

An "ancient" 8086 way is:

xor ch, ch ; set CH (the upper part of CX) to null
mov ax, cx ;preform division
div dl
rkhb
  • 13,273
  • 7
  • 28
  • 49
  • God, I feel silly. thanks for the help, I had thought about using movzx or movsx when planning this and completely forgot. – Mark Gonzalez Apr 29 '17 at 06:08
  • @rkhb I see. I've deleted the comment. – Fifoernik Apr 29 '17 at 12:07
  • If you're going to xor-zero, do `xor ax,ax` / `mov al, cl`. That will [cause partial-register stalls / slowdowns on fewer CPUs](https://stackoverflow.com/questions/41573502/why-doesnt-gcc-use-partial-registers) than zeroing `ch` and then reading `cx`. It's the same code size and should perform identically on real 8086. (On a modern CPU, xor-zeroing `eax` before writing `al` would be much better than only `ax`) – Peter Cordes Dec 13 '17 at 06:28