2016-12-13 14 views
-4

Я использую компилятор 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 
+0

хотите принять вход и присвоить это значение CX register – anila

+0

Как я могу это сделать? – anila

+0

YEs Я просто хочу получить значение от пользователя, который находится в mov bl, al Теперь я хочу присвоить это значение регистру CX, как я могу это сделать? – anila

ответ

2

Вы теряете значение, введенное пользователем в 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 

Edit: шаг значение в CX:

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

@joze Как я могу исправить это, дайте мне знать? Я просто хочу взять значение от пользователя и сохранить его в регистре cx, который является числом. – anila

+0

@ joze в num1 значение переменной сохраняется, я просто хочу передать это значение в регистр cx, как я могу это сделать? – anila

1

BTW: что источник вы вывесили, не может быть скомпилирован (num1 не определен).

В общем случае для загрузки значения из памяти в регистр можно использовать:

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

Пример:

num1: db 7 

Ассемблер будет компилировать это в один байт, содержащий значение 7, и он будет принимать к сведению в таблицу символов, которая имеет метку num1, указывая на этот байт.

num2: dw 0x0809 

Это будет составлен в виде двух байт: 09 08 (не менее значительная часть числа идет сначала в память, так что 09 находится num2 адреса, 08 находится num2+1 адреса). Метка num2 помещается в таблицу символов, указывая на первый байт определенного слова (значение 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. 

Чтобы загрузить 8 битное значение из bl в 16-битный регистр cx у вас есть несколько вариантов, но все по тому же принципу, вы должны продлить 8 битное значение, чтобы быть 16 бит «в ширину».

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 

Для проверки этих работ, запуска кода в отладчике, и смотреть значение реестра для изменения после перешагивая каждую команду.


Ваш обновленный вопрос: «Как отобразить номер в ассемблере x86».

См. https://stackoverflow.com/tags/x86/info, ищите «Как обрабатывать многозначные числа?»

Но сначала вы, вероятно, также должны искать то, что такое ASCII, и как работают «строки» в работе компьютера и как они отличаются от числовых значений в регистре.

На большинстве платформ (DOS тоже) вы не можете просто сделать mov cx,1234 и распечатать это на экране с помощью одной инструкции в виде строки «1234». Вы должны сначала построить строку ASCII, содержащую пять символов 1234$ в некотором буфере памяти (из числового значения 16b в cx), тогда вы можете использовать int 21h,9 для отображения этой строки.

+0

@ ped m, используя num1 db '5' в .data, это правильно? – anila

+0

@anila Это будет компилироваться как одиночный байт со значением '0x35' (hexa) ==' 53' в decimal == '0011 0101' binary == Код ASCII для символа цифры' '5''. Правильно ли это? Зависит, если вы хотите значение 53 в этом байте. Это не номер. ''5' + '5' = 'j''! Поскольку 53 + 53 = 106 и 106 - код ASCII для '' j''. У вас должно быть четкое представление о том, какие значения вы хотите рассчитать. Если вы хотите рассчитать строки ASCII, '' 5'', вероятно, вы хотите. Если вам нужны номера, вы хотите '5'. Если вы хотите отображать числа в виде строки ASCII, вам нужно написать код, который преобразует число в строку ('printf' в C) – Ped7g

+0

@anila разумеет вас, из ваших вопросов, которые вы так запутались, что, если бы я был на вашем место, я бы прекратил печатать что-либо на экране и просто играл с отладчиком, чтобы видеть значения в регистре, и сначала узнал несколько инструкций, манипулируя цифрами и наблюдая за ним в отладчике. Затем сделайте некоторые манипуляции с памятью небольшими задачами, например, установите 10 байт памяти на ноль и т. Д. После этого посмотрите, как выполняется пример «hello world», как «строка» закодирована в памяти компьютера, и что такое ASCII. После этого взгляните на эту функцию форматирования номера в строку из ссылки x86/info. – Ped7g