Want to save value from a variable into register

妖精的绣舞 提交于 2019-12-14 04:14:17

问题


I m using MASM compilor and DOSBOX. I want to Want to save value from a variable into register. i want to save num1 value into cx register. How can i do that?

      .MODEL SMALL
.STACK  50H
.DATA
num1 db '5'
    NL  DB  0DH, 0AH, '$'        
    msg     db ?,0AH,0DH,"Enter an odd number between 0 to 10:$"
     nxtline db 0Ah,0DH,"$"
.CODE
MAIN PROC
    MOV AX, @DATA
    MOV DS, AX



              LEA DX,msg     
              mov ah,9
              int 21H
              LEA DX,nxtline    
              mov ah,9
              int 21H

              MOV AH,1                    
              INT 21H 
              LEA DX,nxtline    
              mov ah,9
              int 21H



       mov bl,al   ;save the value from input
              mov num1,bl
               LEA DX,num1     
              mov ah,9
              int 21H
              mov cl,al 

   main endp
   end main

回答1:


You are losing the value entered by the user in AL. You input one char with this:

          MOV AH,1                    
          INT 21H 

The char is stored in AL, but before you save the value in BL you display a line break:

          LEA DX,nxtline    
          mov ah,9
          int 21H

And the value in AL is gone because this interrupt uses AL to display a string. The solution is to save the value in BL before you display the line break:

          MOV AH,1                    
          INT 21H 
   mov bl,al   ;save the value from input
          LEA DX,nxtline    
          mov ah,9
          int 21H

Edit : move value into CX :

xor cx,cx       ;CLEAR CX.
mov cl,bl       ;MOVE CHAR INTO CL.
sub cl, 48      ;CONVERT CHAR TO DIGIT, EXAMPLE: '5' -> 5.



回答2:


BTW: that source you posted, can't be compiled (num1 not defined).

In general to load value from memory into register you can use:

mov reg8|16|32|64,[<memory_address>]

Example:

num1: db 7

Assembler will compile this into single byte containing value 7, and it will take a note into symbol table, that label num1 exists, pointing at that byte.

num2: dw 0x0809

This will be compiled as two bytes: 09 08 (least significant part of number goes first into memory, so 09 is at num2 address, 08 is at num2+1 address). The num2 label is put into symbol table, pointing at the first byte of the defined word (value 09).

mov bl,[num1]   ; loads value 7 into bl
mov cx,[num2]   ; loads value 0x0809 (8*256+9 = 2057 in decimal) into cx
mov al,[num2]   ; loads value 9 into al
mov ah,[num2+1] ; loads value 8 into ah = now ax contains 2057. (ax = ah:al)
mov dx,[num1]   ; will load dl with 7, and dh with something what is after it
  ; if you wanted "num1", then this is bug, as "num1" is only 1 byte "wide"
  ; and dx is 16 bit register, so it's two bytes wide.

To load 8 bit value from bl into 16 bit register cx you have several options, but all follow the same principle, you have to extend the 8 bit value to be 16 bit "wide".

mov cl,bl   ; set's lower 8 bits of cx to bl, doesn't care about upper 8 bits
  ; ^ unless done on purpose, this is bug, as "cx" has unexpected value

movzx cx,bl ; "zx" = zero-extend, value 0xFE (254) will become 0x00FE (254)
  ; recommended way for 386+ code (does not exist on 8086-80286 CPUs)

movsx cx,bl ; "sx" = sign-extend, so value 0xFE (-2) will become 0xFFFE (-2)
  ; recommended way for 386+ code (does not exist on 8086-80286 CPUs)

xor cx,cx   ; cx = 0
mov cl,bl   ; same as first example, but ch was set to zero with previous ins.
  ; recommended way for 8086 code

mov ch,bl  ; ch = bl, cl undefined
sar cx,8   ; cx = sign extended bl to 16 bits (bl=0xFE will set cx=0xFFFE)
  ; "recommended" way for 8086 code (not really, but who cares about 8086 anyway)
  ; for al -> ax sign extension there's specialized CBW instruction


mov cl,bl      ; cl = bl, ch undefined
and cx,0x00FF  ; AND with 0x00FF will clear ch, and keep cl
  ; not recommended (slower), just example that any valid math works of course

To verify these works, launch the code in debugger, and watch the values of register to change after stepping over each instruction.


Your updated question is "how to display number in x86 assembler".

See https://stackoverflow.com/tags/x86/info , search for "How do I handle multi-digit numbers?"

But at first you should probably also search what is ASCII, and how "strings" in computer work, and how they differ from numeric values in register.

On most of the platforms (DOS too) you can't just do mov cx,1234 and print that on screen with single instruction as string "1234". You have to first build an ASCII string containing five characters 1234$ in some memory buffer (from the 16b numeric value in cx), then you can use int 21h,9 to display that string.



来源:https://stackoverflow.com/questions/41127123/want-to-save-value-from-a-variable-into-register

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!