Хотите сохранить значение из переменной в регистр

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

person anila    schedule 13.12.2016    source источник
comment
хотите принять ввод и присвоить это значение регистру CX   -  person anila    schedule 13.12.2016
comment
Как я могу это сделать?   -  person anila    schedule 13.12.2016
comment
Да, я просто хочу получить значение от пользователя, который находится в mov bl, al. Теперь я хочу присвоить это значение регистру CX. Как я могу это сделать?   -  person anila    schedule 13.12.2016
comment
Да m получение @ joze через MOV AH,1 INT 21H   -  person anila    schedule 13.12.2016
comment
после этого m получает входное значение в bl через mov bl,al. Теперь я хочу присвоить это значение регистру CX, как я могу это сделать @ joze   -  person anila    schedule 13.12.2016
comment
@anila - используйте xor cx,cx | мов кл,ал . Если вам нужно число, вы, вероятно, захотите использовать sub al,030h для преобразования Ascii «0» в «9» в значения от 0 до 9.   -  person rcgldr    schedule 13.12.2016
comment
Да, я хочу присвоить числовое значение регистру cx Как я могу это сделать, я сделал то, что вы сказали, но не получил результатов   -  person anila    schedule 13.12.2016
comment
Анила, делай, как тебе сказал @rcgldr.   -  person Jose Manuel Abarca Rodríguez    schedule 13.12.2016
comment
Всего минута @ joze m редактирую мой код, теперь вы можете видеть   -  person anila    schedule 13.12.2016
comment
@ joze, теперь скажи мне, как я могу это сделать   -  person anila    schedule 13.12.2016
comment
В более общем случае, если AL содержит число со знаком, вы можете использовать CBW; MOV CX,AX.   -  person Weather Vane    schedule 13.12.2016
comment
@rcgldr после получения значения с помощью этого xor cx,cx | mov cl,al по-прежнему не назначает его   -  person anila    schedule 13.12.2016
comment
где код?   -  person demongolem    schedule 13.12.2016


Ответы (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

Изменить : переместить значение в CX :

xor cx,cx       ;CLEAR CX.
mov cl,bl       ;MOVE CHAR INTO CL.
sub cl, 48      ;CONVERT CHAR TO DIGIT, EXAMPLE: '5' -> 5.
person Jose Manuel Abarca Rodríguez    schedule 13.12.2016
comment
@joze, как я могу это исправить, дайте мне знать? Я просто хочу взять значение от пользователя и сохранить его в регистре cx, который является числом. - person anila; 13.12.2016
comment
@joze в значении переменной num1 хранится, я просто хочу переместить это значение в регистр cx, как я могу это сделать? - person anila; 13.12.2016

Кстати: тот источник, который вы разместили, не может быть скомпилирован (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 для отображения этой строки.

person Ped7g    schedule 13.12.2016
comment
@anila Это будет компилироваться как один байт со значением 0x35 (шестнадцатеричный) == 53 в десятичном виде == 0011 0101 двоичный == Код ASCII для цифрового символа '5'. Правильно ли это? Зависит от того, хотите ли вы значение 53 в этом байте. Это не число. '5' + '5' = 'j'! Потому что 53+53 = 106, а 106 — это код ASCII для 'j'. У вас должно быть четкое представление о том, какие значения вы хотите рассчитать. Если вы хотите вычислить строки ASCII, '5', вероятно, то, что вам нужно. Если вам нужны цифры, вам нужны 5. Если вы хотите отображать числа в виде строки ASCII, вам нужно написать код, который преобразует число в строку (printf в C) - person Ped7g; 13.12.2016
comment
@anila Имейте в виду, из ваших вопросов вы выглядите таким растерянным, что если бы я был на вашем месте, я бы перестал печатать что-либо на экране, а просто поигрался бы с отладчиком, чтобы увидеть значения в регистре, и сначала выучить несколько инструкций, манипулируя числа и просмотр его в отладчике. Затем выполните небольшие манипуляции с памятью, например, обнулите 10 байтов памяти и т. д. После этого посмотрите, как выполняется пример hello world, как строка кодируется в памяти компьютера и что такое ASCII. После этого взгляните на эту функцию форматирования числа в строку из ссылки x86/info. - person Ped7g; 13.12.2016
comment
@anila вы можете буквально посмотреть в своем браузере, как работает более простая вымышленная 8-битная машина, на примере hello world: schweigi .github.io/assembler-simulator ... отправьте сборку и посмотрите, как память заполняется скомпилированным кодом. затем перешагните через него и выделите регистры C и D, обратите внимание, как текст отображается на верхнем текстовом дисплее, когда он записывается в конец памяти (видеопамять). Это похоже на то, как текстовые режимы VGA работали в DOS, и на то, что делает int 21h,9 (до того, как видеопамять текстового режима эмулируется графическим пикселем с помощью dosbox в вашей реальной ОС). - person Ped7g; 13.12.2016