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