2

I'm trying to take a number input from the user and print stars equal to that number...

mov ah, 1h
int 21h
mov dl, '*'
mov cx,al
mov ah,2h

l1:
int 21h
loop l1

But i'm getting the following error...

(4) wrong parameters: MOV  cx,al
(4) operands do not match: 16 bit and 8 bit register 
user3520573
  • 137
  • 1
  • 6
  • 13
  • 3
    What is it that you don't understand about this error message? One register is 16 bit, the other is 8 bit. You can't fit the contents of one into the other. Not enough space. Use a different register. Or mask off the top 8 bits first. – Floris Jun 17 '14 at 22:24
  • How will i mask off the top 8 bits? please tell me! – user3520573 Jun 17 '14 at 22:30
  • 1
    Try using | mov ch,0 | mov cl,al | ... or ... | xor cx,cx | mov cl,al | . – rcgldr Jun 17 '14 at 22:38
  • 3
    Actually this is a mov into a 16 bit register from a 8 bit register, so there is plenty of space :) You could use `movzx cx, al`. – Jester Jun 17 '14 at 23:38
  • ...or if this is for an antique, you can replace "mov cx, al" with a "cbw" (or possibly a "xor ah, ah"), "mov cx, ax" combo since you're overwriting ah afterwards anyways. – Brian Knoblauch Jun 18 '14 at 13:37
  • Possible duplicate of [Cannot move 8 bit address to 16 bit register](https://stackoverflow.com/questions/33959446/cannot-move-8-bit-address-to-16-bit-register) – phuclv Mar 07 '18 at 13:28

1 Answers1

0

Nice problem.

My little opinion, particularly if you are new to assembly language: The comments will help you debug your code better than anything else.

I've taken your stuff, and added comments, and also added one line of code which (I hope) will fix your problem; this one...

Sub Cx,Cx ; We're really only after the top half here

As others have mentioned, you can use the Mov Ch, 0 instruction or the Xor Ch, Ch and there are others as well. The subtraction thing does the job completely, and is pretty obvious to the reader; helps like everything when you're debugging.

(The Xor Ch, Ch stuff goes way back; way way back; to when that instruction was the fastest way to make a register zero. This is no longer true.)

So anyway, the assembler is angry with you because you told him to move AL, an 8 bit register, into CX, a 16 bit register. While that is possible with some instructions that came along later, I seriously doubt that that's what you want.

Okay, so, after making the complete Cx register zero, I changed your line 4 to this...

Mov Cl,Al ; Cx is now the counter for our loop

Here's your stuff with that one additional line and the other one line change

 ;------------------------------------------------------------------.
 ;                                                                  ;
 ;   Ms-Dos assembly language routine to print X Number of stars    ;
 ;                                                                  ;
 ;   On Entry:      Nothing                                         ;
 ;                                                                  ;
 ;   On Exit:       Nothing                                         ;
 ;                                                                  ;
 ;                  AX, CX, DX are all meaningless after this code  ;
 ;                                                                  ;
 ;                  Flags don't mean anything either                ;
 ;                                                                  ;
 ;   Scheme:        Get a single character input from the user      ;
 ;                                                                  ;
 ;                  Use that as the count                           ;
 ;                                                                  ;
 ;                  Print that many stars                           ;
 ;                                                                  ;
 ;                                                                  ;
 ;                                                                  ;
 ;------------------------------------------------------------------'


 Print_Stars: 

    Mov Ah, 1h              ; 1h means get one char 
    Int 21h                 ; Ms.Dos puts it into AL for us 

    Sub Cx,Cx               ; We're really only after the top half here 
    Mov Cl,Al               ; Cx is now the counter for our loop 

    Mov Dl, '*'             ; Ms.Dos wants the character in this reg 
    Mov Ah,2h               ; This will tell her to print that one char 

 The_Loop_1: 

    Int 21h                 ; Ms.Dos puts the character in DL on the screen 
    Loop The_Loop_1         ; And we repeat as often as the user wanted 
    : 
    : 
    :                       ;  (Whatever, whatever) 
    : 
    : 
    : 

So far, so good.

At this moment, I believe that you think your only error is your line 4, operands do not match: 16 bit and 8 bit register.

Nope, You have one more annoyance in front of you; Ascii isn't Binary; not by a long shot

In fact, if I'm counting properly, when you press 7 on your keyboard, you'll probably see something like 55 stars on the screen. What gives ?

Ascii "7" is actually 37h

This is easily fixed, you subtract 30h from AL after Ms.Dos returns it to you from the user's keystroke.

Here's an old trick from way-back-when, it was useful to writers (and debuggers) back then; see if it's useful to you today.

It is possible to adjust the value by subtracting the Ascii character "0" itself. The assembler is smart enough to know what you are doing. It looks like this...

    Sub Al, '0'             ; Make ascii digit into real binary number

Okay, so, change your first two lines to these first three lines and watch the magic...

    Mov Ah, 1h              ; 1h means get one char 
    Int 21h                 ; Ms.Dos puts it into AL for us 
    Sub Al, '0'             ; Make ascii digit into real binary number

Hope this helps.

User.1
  • 2,562
  • 3
  • 33
  • 40