想要将变量的值保存到寄存器中

Want to save value from a variable into register

我正在使用 MASM 编译器和 DOSBOX。我想将变量的值保存到寄存器中。我想将 num1 值保存到 cx 寄存器中。我该怎么做?

      .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

顺便说一句:您发布的源代码无法编译(num1 未定义)。

一般来说,要将值从内存加载到寄存器中,您可以使用:

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

示例:

num1: db 7

汇编程序会将其编译成包含值 7 的单个字节,并将注释记入符号 table,标签 num1 存在,指向该字节。

num2: dw 0x0809

这将被编译为两个字节:09 08(数字的最低有效部分首先进入内存,因此 09num2 地址,08num2+1 地址)。 num2 标签被放入符号 table 中,指向定义字的第一个字节(值 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.

要从 bl 加载 8 位值到 16 位寄存器 cx 你有几种选择,但都遵循相同的原则,你必须将 8 位值扩展为 16 位 "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

要验证这些工作,在调试器中启动代码,并在单步执行每条指令后观察寄存器值的变化。


您更新后的问题是 "how to display number in x86 assembler"。

查看 https://whosebug.com/tags/x86/info ,搜索 "How do I handle multi-digit numbers?"

但首先您可能还应该搜索什么是 ASCII,以及 "strings" 在计算机中的工作原理,以及它们与寄存器中的数值有何不同。

在大多数平台(也包括 DOS)上,您不能只执行 mov cx,1234 并使用单个指令将其打印在屏幕上,如字符串“1234”。你必须首先在一些内存缓冲区中构建一个包含五个字符 1234$ 的 ASCII 字符串(来自 cx 中的 16b 数值),然后你可以使用 int 21h,9 显示该字符串。

您正在丢失用户在 AL 中输入的值。你用这个输入一个字符:

          MOV AH,1                    
          INT 21H 

字符存储在 AL 中,但在将值保存在 BL 中之前显示换行符:

          LEA DX,nxtline    
          mov ah,9
          int 21H

AL中的值没有了,因为这个中断使用了AL来显示一个字符串。解决方法是在BL中保存值,然后显示换行符:

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

编辑 : 将值移入 CX :

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