问题
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