Как добавить в сборку? - PullRequest
0 голосов
/ 27 мая 2019

Я пытаюсь сделать калькулятор в сборе. Вы вводите две переменные, а затем выбираете операцию. Теперь операция является только дополнением. Я работаю только с прерываниями BIOS, без DOS. Может кто-нибудь объяснить мне, как это сделать? У меня две проблемы, и я застрял с ними:

  1. Первая проблема, когда я добавляю 5 + 6, например, он возвращает 59 (48 + 11) в ASCII. Я думаю, что решение было бы печатать в десятичном формате, но я ничего не нашел в Интернете, используя только прерывания BIOS.
  2. Вторая проблема заключается в том, что когда я добавляю 49 + 59, он возвращает 9, поэтому добавляет только первые символы.

Код:

    firstVariableKeyboard: ;store in var1 first variable
        mov ah,0x0
        int 16h ;keyboard interrupt

        cmp al,0x0d
        je returnEnter

        mov ah,0eh ;tty mode
        int 10h

        mov byte [var1 + bx],al
        inc bx

        jmp firstVariableKeyboard

    secondVariableKeyboard: ;store in var2 second variable
        mov ah,0x0
        int 16h

        cmp al,0x0d
        je returnEnter

        mov ah,0eh
        int 10h

        mov byte [var2 + bx],al
        inc bx

        jmp secondVariableKeyboard

   equalMath:
        ;introduce first variable
        mov si,math_description0
        call printString

        mov bx,0
        call firstVariableKeyboard
        mov dl,[var1]
        ;conversion from ascii to decimal
        sub dl, '0'

        ;new line
        mov si,newLine
        call printString

        ;introduce second variable
        mov si,math_description1
        call printString

        mov bx,0
        call secondVariableKeyboard
        mov dh,[var2]
        ;conversion from ascii to decimal
        sub dh, '0'

        ;new line
        mov si,newLine
        call printString

        ;the result
        mov si,math_description2
        call printString

        ;adding
        add dl, dh
        ;conversion from decimal to ascii
        add dl, '0'

        mov byte [result], dl
        mov si,result
        call printString

        ;new line
        mov si,newLine
        call printString

        jmp mainLoop

printString:
    push ax                   ; save ax to stack

    mov ah, 0x0e              ; call tty function
    call printChar      

    pop ax                    ; take ax out of the stack
    ret                      
printChar:
    mov al, [si]              ; load symbol

    cmp al, 0                 ; if si empty then jump
    jz ifZero               

    int 0x10                  ; if not print al
    inc si                    ; increment si

    jmp printChar       ;again untill stack empty
ifZero:
    ret

    var1: times 64 db 0 
    var2: times 64 db 0 
    result:  times 64 db 0 
  1. 5 + 6 = 11 пример
    5+6=11 example
  2. пример два символа + два символа
    two char + two char example

1 Ответ

1 голос
/ 27 мая 2019

Два вопроса почти одинаковы.Вы пытаетесь представить число, содержащее 2 цифры, с 1 байтом ASCII.Вам нужно зациклить ваш ввод И на вашем выходе.Позволь мне объяснить.Заранее извиняюсь, что пример 64-битный ... вы не опубликовали свой полный код, поэтому я просто побежал с тем, что я знал лучше всего, чтобы написать этот ответ.

По сути, вы делаете это: (53 - 48) + (54 - 48).Это дает нам значение 11. Пока все хорошо.Что такое значение ASCII для представления 11 как одного символа ?

Нет one .Что вам нужно, это напечатать символ '1', дважды (чтобы сформировать строку "11").

Затем вам нужно преобразовать число, которое имеет более 1 цифры, встрока.Возможно, было бы достаточно что-то вроде itoa функции в стандартной библиотеке C.

По сути, вам нужно перебрать число и преобразовать каждую цифру в символ, чтобы сформировать строку, которую вы можетеРаспечатать.Вы можете сделать это, разделив число на 10 на каждой итерации и проверив остаток. Вот пример, работающий на IDEOne

Ядром itoa примера является цикл деления:

.divloop:
    xor rdx,rdx         ; Zero out rdx (where our remainder goes after idiv)
    idiv rcx            ; divide rax (the number) by 10 (the remainder is placed in rdx)
    add rdx,0x30        ; add 0x30 to the remainder so we get the correct ASCII value
    dec rdi             ; move the pointer backwards in the buffer
    mov byte [rdi],dl   ; move the character into the buffer
    inc dword [rbp-4]   ; increase the length

    cmp rax,0           ; was the quotient zero?
    jnz .divloop        ; no it wasn't, keep looping

Давайте запустим число 59 из вашего второго примерашаг за шагом:

Текущий буфер:

[0][0][0][0][0][0][0][0][0][0]

Первая итерация:

59 / 10 = 5 remainder 9
9 + 48 = 57 (the ASCII value of '9')

[0][0][0][0][0][0][0][0][0][57]
                            ^ place the ASCII value in the buffer, decrease the pointer and update the number to be the quotient from the idiv instruction

Итак, если мы распечатаем это сейчас, мы получим число 9Коэффициент не был равен нулю, поэтому мы снова зациклимся:

5 / 10 = 0 remainder 5
5 + 48 = 53 (the ASCII value of '5')

[0][0][0][0][0][0][0][0][53][57]
                          ^ place the ASCII value in the buffer, decrease the pointer and update the number to be the quotient from the idiv instruction

Коэффициент равен нулю на этой последней итерации, поэтому мы не зацикливаемся и не завершаем функцию.

Эти два байта в буфере теперь 53 и 57, которые являются значениями ASCII символов 5 и 9 соответственно.Если бы вы должны были напечатать этот буфер на свой стандартный вывод, он бы вывел строку "59" (эта функция примера также возвращает длину полученной строки, чтобы ее можно было правильно распечатать).

Существует аналогичноепроблема с вашим вкладом.Вы передаете строки «49» и «59» и читаете только самый первый символ.Вам нужно перебрать эту строку и преобразовать ее в целое число.Это должно быть довольно просто, поэтому я оставлю это как упражнение для вас.

Причина, по которой второй пример «работает» (он печатает число, которое вы ожидаете), связана с ошибкой выше.Вы складываете только 4 и 5 вместе, в результате получается 9 - число, состоящее из одной цифры.

Надеюсь, это поможет.

...