想要将变量的值保存到寄存器中
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
(数字的最低有效部分首先进入内存,因此 09
在 num2
地址,08
在 num2+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.
我正在使用 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
(数字的最低有效部分首先进入内存,因此 09
在 num2
地址,08
在 num2+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.