преобразовать строку в десятичную на ассемблере - PullRequest
0 голосов
/ 25 апреля 2019

Я пытаюсь преобразовать строку в десятичную, а затем добавить все числа до этой десятичной дроби (например, если число равно 5, мне нужно добавить 1 + 2 + 3 + 4 + 5), а затем распечатать это число послепреобразование его обратно в десятичное.

Я пытаюсь выполнить следующие шаги, код не завершен, до сих пор я просто конвертирую строку в десятичную и проверяю, преобразована ли она, есть какая-то ошибка

title       fill in title 

;------------------------------------------------------------------------------
stacksg segment     para stack 'Stack'
    db 32 dup(0)


stacksg ends
;---------------------------------------------------------------------------------------------
datasg segment para 'Data'
paralst label byte
maxlen DB 20
actlen DB ?
indata DB 20 dup ('$')
strout DB "Enter a number between 1 and 20: $"
errors DB "USER ERROR$"
sum DB "The sum is: $"
datasg ends
;-----------------------------------------------------------------------------------
codesg segment para 'Code'
main    proc    far
assume ss:stacksg, ds:datasg, cs:codesg 
mov ax, datasg ;initialize data segment registers
        mov ds, ax
        mov es, ax

        MOV AH, 06H
        MOV AL, 0
        MOV CX, 0  ; ch-row, cl-columns
        MOV DH, 79
        MOV DL, 79

        MOV BH, 01000000B

        int 10H

        Mov AH, 02H
        MOV BH, 00H
        MOV DH, 12  ; or mov dx 0c28h
        MOV DL, 25
        INT 10H

        MOV AH, 09H
        LEA DX, STROUT
        INT 21H

        Mov AH, 0AH
        LEA DX, paralst
        int 21H

;converting string to decimal

         CALL READ_NUM 

     READ_NUM Proc Near

        push BX
        push CX
        push DX

        LEA BX, indata
        Mov AX, 0
        Mov CX, 0
        Mov DL, 10

        again: 
        MOV CL, [BX]
        CMP CL, 0DH
        JE THEEND
        SUB CX, 30H
        MUL DL
        ADD AX, CX
        INC BX

        THEEND: 

        POP DX
        POP CX
        POP BX ; conversion complete

        CMP AX, 20  ; since converted decimal is in AX,
                    ; i am checking if it is over 20 or below 1....
                    ; there is where i get error.
        JG ERRS
        CMP AX, 1
        JL ERRS
        mov     ax, 4c00h   
        int 21h


        MOV DX, 0
        MOV CX, 1

        TOPPY:

        CMP DX, AX
        JG ENDDY
        ADD CX, DX
        INC DX
        JMP TOPPY



        ERRS:

        Mov AH, 02H
        MOV BH, 00H
        MOV DH, 15  ; or mov dx 0c28h
        MOV DL, 25
        INT 10H

        MOV AH, 09H
        LEA DX, errors
        INT 21H

        mov     ax, 4c00h   
        int 21h


        ENDDY:
        Mov AH, 02H
        MOV BH, 00H
        MOV DH, 16  ; or mov dx 0c28h
        MOV DL, 25
        INT 10H

        MOV AH, 09H
        LEA DX, sum
        INT 21H

                mov ax, 4c00h   
        int 21h

        Ret
        READ_NUM endp

        main endp       ;end of procedure


        codesg ends ;end of code segment    
        end main    ;end of program

1 Ответ

0 голосов
/ 25 апреля 2019
    LEA BX, indata
    Mov AX, 0
    Mov CX, 0
    Mov DL, 10

   again: 
    MOV CL, [BX]
    CMP CL, 0DH
    JE THEEND
    SUB CX, 30H
    MUL DL
    ADD AX, CX
    INC BX

  THEEND: 

У вас есть некоторые ошибки здесь:

  1. Вы на самом деле не делаете цикл в этом коде. Переход к снова отсутствует .
  2. Вы забыли, что это подпрограмма (которую вы call ed), и поэтому вы должны вернуться из нее, используя инструкцию ret.
  3. Требуемый READ_NUM endp слишком далеко в программе.

Может ли быть так, что пункты 2 и 3 являются результатом ваших усилий по отладке?

READ_NUM Proc Near
  push bx
  push cx
  lea  bx, indata
  mov  al, 0      ;Clear result
again: 
  mov  cl, 10
  mul  cl         ;AX = AL * CL
  mov  cl, [bx]
  cmp  cl, 13
  je   THEEND
  sub  cl, '0'
  add  al, cl     ;Add in new digit
  adc  ah, 0
  inc  bx
  jmp  again      <<<< you missed this one!!
THEEND: 
  pop  cx
  pop  bx         ;Conversion complete
  ret             <<<< you missed this one!
READ_NUM endp

Пожалуйста, переместите весь READ_NUM процесс ниже DOS. Замените, чтобы ваш код случайно не упал в него:

  mov ax, 4C00h   
  int 21h

READ_NUM Proc Near
  push bx

paralst label byte
maxlen DB 20
actlen DB ?
indata DB 20 dup ('$')

Поскольку вы запрашиваете числовой ввод от 1 до 20, вы можете ограничить этот буфер до 2 символов. Это позволило бы ввести не более 99. Используя умножение в байтах, ваш алгоритм в любом случае может поддерживать только числа от 0 до 255.

paralst label byte
maxlen DB 3          ;2 characters and 1 carriage return
actlen DB ?
indata DB 3 dup (0)

  CMP AX, 20  ; since converted decimal is in AX,
                ; i am checking if it is over 20 or below 1....
                ; there is where i get error.
    JG ERRS
    CMP AX, 1
    JL ERRS
    mov     ax, 4c00h   
    int 21h

Даже без необходимого jmp again, если это дополнение для отладки работало бы хорошо с вводом одной цифры.


  MOV DX, 0
    MOV CX, 1

   TOPPY:

   CMP DX, AX
    JG ENDDY
    ADD CX, DX
    INC DX
    JMP TOPPY

Неправильно вычислять сумму чисел до введенных. Число 1 добавляется дважды!
Ниже показано, что намного проще, если вы начнете добавлять сверху вниз:

               ;AX=5 (input)
 xor cx, cx
more:
 add cx, ax    ;+5 +4 +3 +2 +1
 dec ax
 jnz more
               ;CX=15

Чтобы напечатать этот двузначный результат, вы можете прочитать this .

...