Error “operands do not match: 16 bit and 8 bit register” in assembly language

前端 未结 1 1693
逝去的感伤
逝去的感伤 2021-01-15 14:41

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
lo         


        
1条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-15 14:58

    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.

    0 讨论(0)
提交回复
热议问题