Напечатать "да", если введенное число делится на 3 и на 2 одновременно... - Assembler

Узнай цену своей работы

Формулировка задачи:

Здравствуйте, уже не первый день пытаюсь написать программу по заданию: "Напечатать "да", если введенное число делится на 3 и на 2 одновременно, "или", если делится или на 3 или на 2, "нет", если не делится ни на 3, ни на 2." Все время ошибка во время компиляции, но никак не могу ее найти и исправить, надеюсь Вы мне поможете. P.S. Pascal с Assembler-вставкой.

Решение задачи: «Напечатать "да", если введенное число делится на 3 и на 2 одновременно...»

textual
Листинг программы
;
; MASM Forever
;
.186
.MODEL TINY, STDCALL
OPTION CASEMAP: NONE
;
CHAR  TYPEDEF     Byte
PCHAR TYPEDEF     Ptr CHAR
PSTR  TYPEDEF     PCHAR
PW    TYPEDEF     Ptr Word
PSKB  TYPEDEF     Ptr KBINP
;
CR          EQU   0Dh
LF          EQU   0Ah
MaxChars    EQU   80
KbInpLen    EQU   MaxChars
MaxNumbLen  EQU   MaxChars/4
;
KBINP STRUCT
nbMax Byte  ?
nbInp Byte  ?
chBuf CHAR  KbInpLen Dup (?)
KBINP ENDS
;
decStr2BinNum     PROTO pStrDec:PSTR, lenStrDec:Word, pwNumb:PW, lenwNumb:Word
binNum2DecStr     PROTO pwNumb:PW, lenwNumb:Word, pCharBuf:PCHAR
stdIn2Sc          PROTO psKb:PSKB, KbLen:Word
s$2StdOut         PROTO pSd:PSTR
;
.DATA
s$AppInfo   CHAR  "Cascade Multiplication/Division Demo Program", CR, LF
            CHAR  "Coded in Masm by KyberMax  (C:) TeraHard Labs  2016"
s$CrLf      CHAR  CR, LF, "$"
s$Input     CHAR  "Input Dec.Number (empty string - exit)", CR, LF, "$"
s$Output    CHAR  "Dec.Number after DecStr->BinNum->DecStr", CR, LF, "$"
s$WrongCh   CHAR  " wrong char", CR, LF, "$"
;
.DATA?
nwNumb      DW    MaxNumbLen  Dup (?)
sKbInp      KBINP <>
chDecOut    CHAR  MaxChars    Dup (?)
;
.CODE
      ORG   100h
START:
      INVOKE s$2StdOut, Addr s$AppInfo
DEMO_LOOP:
      INVOKE s$2StdOut, Addr s$Input
      INVOKE stdIn2Sc, Addr sKbInp, KbInpLen
      INVOKE s$2StdOut, Addr s$CrLf
      JCXZ  EXIT
      INVOKE decStr2BinNum, BX, CX, Addr nwNumb, LengthOf nwNumb
      JNC   NUM2DEC
      INVOKE s$2StdOut, Addr s$WrongCh
      JMP   DEMO_LOOP
NUM2DEC:
      INVOKE s$2StdOut, Addr s$Output
      INVOKE binNum2DecStr, Addr nwNumb, LengthOf nwNumb, Addr chDecOut
      MOV   CHAR Ptr [BX], "$"
      INVOKE s$2StdOut, Addr chDecOut
      INVOKE s$2StdOut, Addr s$CrLf
      JMP   DEMO_LOOP
EXIT:
      RET
;
decStr2BinNum PROC Uses AX BX DX DI SI pstdec:PSTR, lstdec:Word, pwnumb:PW, lwnumb:Word
; Output: if error CF = 1
;         else     CX = word number
LOCAL lwcur:Word
      XOR   AX, AX
      MOV   DI, pwnumb
      MOV   CX, lwnumb  ; Length in words
      REP STOSW         ; Numb = 0
      MOV   lwcur, 1    ; Start with 1 word
      MOV   SI, pstdec
      MOV   BX, 10
numloop:
      XOR   AH, AH
      LODSB
      SUB   AL, "0"
      JC    exit
      CMP   AL, 10
      CMC
      JC    exit
      PUSH  SI
      PUSHF
      MOV   SI, AX
      MOV   DI, pwnumb
      MOV   CX, lwcur
mulloop:
      MOV   AX, [DI]
      MUL   BX
      XCHG  DX, SI
      POPF
      ADC   AX, DX
      PUSHF
      STOSW
      LOOP  mulloop
      POPF
      ADC   [DI], SI
      JZ    nextchar
      INC   lwcur
nextchar:
      POP   SI
      DEC   lstdec
      JNZ   numloop
      CLC
      MOV   CX, lwcur
exit:
      RET
decStr2BinNum ENDP
;
binNum2DecStr PROC Uses AX DX DI SI pwnumb:PW, lwnumb:Word, pchbuf:PCHAR
; Output: CX = number of chars
;         BX = pointer to next char
; Notice: destroys wnumb
      MOV   AX, lwnumb  ; Length in words
      DEC   AX
      SHL   AX, 1
      ADD   pwnumb, AX  ; Pointer to most signif.word
      MOV   BX, 10
      MOV   SI, pchbuf
      STD
numloop:
      XOR   DX, DX
      MOV   CX, lwnumb
      MOV   DI, pwnumb
skip0loop:
      CMP   [DI], DX
      JNZ   savelp
      SUB   DI, SizeOf Word
      LOOP  skip0loop
      CMP   SI, pchbuf
      JNE   reverstring
      CALL  savedigit
      JMP   reverstring
savelp:
      PUSH  numloop
      MOV   lwnumb, CX
      MOV   pwnumb, DI
divloop:
      MOV   AX, [DI]
      DIV   BX
      STOSW
      LOOP  divloop
savedigit:
      ADD   DL, "0"
      MOV   [SI], DL
      INC   SI
      RETN
reverstring:
      CLD
      MOV   BX, SI      ; Save pointer to next char
      MOV   CX, SI
      DEC   SI          ; Pointer to last digit
      MOV   DI, pchbuf  ; Pointer to first digit
      SUB   CX, DI      ; Number of digits
      MOV   DX, CX      ; Save for exit
      SHR   CX, 1       ; /2
      JCXZ  exit        ; 1 digit
reverloop:
      MOV   AL, [DI]
      XCHG  [SI], AL
      STOSB
      DEC   SI
      LOOP  reverloop
exit:
      MOV   CX, DX
      RET
binNum2DecStr ENDP
;
stdIn2Sc PROC Uses AX DX pskb:PSKB, kblen:Word
; Output: BX = poitner to keyboard buffer
;         CX = chars.numb.
      MOV   BX, pskb
 ASSUME BX: Ptr KBINP
      MOV   AL, Byte Ptr kblen
      MOV   [BX].nbMax, AL
      MOV   DX, BX
      MOV   AH, 0Ah
      INT   21h
      XOR   CH, CH
      MOV   CL, [BX].nbInp
      LEA   BX, [BX].chBuf
 ASSUME BX: Nothing
      RET
stdIn2Sc ENDP
;
s$2StdOut PROC Uses AX DX ps$:PCHAR
      MOV   DX, ps$
      MOV   AH, 9
      INT   21h
      RET
s$2StdOut ENDP
;
END START
;

Объяснение кода листинга программы

Код написан на языке ассемблера (MASM) и реализует программу, которая выполняет следующую задачу:

  1. Определение и инициализация необходимых констант и типов данных.
    • Определение констант CR (каретка), LF (перевод строки), MaxChars (максимальная длина строки), KbInpLen (максимальная длина ввода числа), MaxNumbLen (максимальная длина введенного числа в десятичной системе счисления).
    • Определение пользовательских типов данных CHAR, PCHAR, PSTR, PW, PSKB.
    • Определение структуры KBINP, содержащей информацию о вводе с клавиатуры.
  2. Объявление необходимых переменных.
    • Объявление и инициализация строковых переменных s$AppInfo, s$CrLf, s$Input, s$Output, s$WrongCh.
    • Объявление числовых переменных nwNumb, sKbInp, chDecOut.
  3. Определение процедур и функций.
    • Определение процедур decStr2BinNum и binNum2DecStr для конвертации числа из десятичной системы счисления в двоичную и наоборот.
    • Определение процедур stdIn2Sc и s$2StdOut для чтения данных с клавиатуры и вывода данных на экран.
  4. Описывается логика работы программы.
    • Инициализация программы и вывод информации о программе.
    • Бесконечный цикл демонстрации программы.
      • Вывод просьбы о вводе числа и получение введенных данных с клавиатуры.
      • Если введенная строка пуста, программа завершается.
      • Конвертация введенного числа из строкового представления в двоичное число.
      • Если введенное число содержит недопустимые символы, выводится сообщение о некорректном символе и цикл продолжается.
      • Конвертация двоичного числа обратно в строковое представление.
      • Вывод строки исходного числа и полученного числа.
    • Завершение программы. Описанный код является примером программы на языке ассемблера (MASM) для выполнения задачи по конвертации числа из десятичной системы счисления в двоичную и наоборот.

Оцени полезность:

6   голосов , оценка 4.667 из 5
Похожие ответы