|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
14.01.2023, 13:17 | #1 |
Пользователь
Регистрация: 14.01.2023
Сообщений: 38
|
Упростить и сократить код
[CODE]; TASM Вычислить Выражение (переменные вводятся с клавиатуры) a*c*(a+b)-d
; a, b, c – define byte, d – define word .model small .code a db 0 b db 0 c db 0 d dw 0 res dw 0 start: mov ax,cs mov ds,ax mov es,ax call pthis db "'a*c*(a+b)-d' calculator",13,10,0 call pthis db 13,10,"byte a=",0 call scan_byte mov a,cl call pthis db 13,10,"byte b=",0 call scan_byte mov b,cl call pthis db 13,10,"byte c=",0 call scan_byte mov c,cl call pthis db 13,10,"word d=",0 call scan_num mov d,cx mov al,a mov bl,b mov ah,0 mov bh,0 add ax,bx cmp ah,0 jnz over1 mov ah,c mul ah ; ax=c*(a+b) mov cx,ax mov al,a mov ah,0 mul cx ; ax=a*c*(a+b) cmp dx,0 jnz over1 sub ax,d ; ax=a*c*(a+b)-d mov res,ax call pthis db 13,10,"result=",0 mov ax,res call print_num int 20h ; выход в Дос over1: call pthis db "Number is out of bounds",0 int 20h ; выход в Дос scan_byte:call scan_num ; ввести число cmp ch,0 ; число не умещается в байт ? jnz over1 ret ; иначе возврат ;**************************** ; include io86.inc ; *************************** ; Подпрограммы ввода и вывода ; *************************** ; this macro prints a char in AL and advances ; the current cursor position: ; макро - вывод символа char на дисплей PUTC MACRO char PUSH AX push dx MOV DL, char MOV AH, 2 INT 21h pop dx POP AX ENDM ; ; CALL PTHIS ; db 'Hello World!', 0 ; PTHIS: MOV CS:temp1, SI ; store SI register. POP SI ; get return address (IP). PUSH AX ; store AX register. next_char: MOV AL, CS:[SI] INC SI ; next byte. CMP AL, 0 JZ printed MOV AH, 0Eh ; teletype function. INT 10h JMP next_char ; loop. printed: POP AX ; re-store AX register. ; SI should point to next command after ; the CALL instruction and string definition: PUSH SI ; save new return address into the Stack. MOV SI, CS:temp1 ; re-store SI register. RET temp1 DW ? ; variable to store original value of SI register. ; ввод числа CX со знаком SCAN_NUM: PUSH DX PUSH AX PUSH SI MOV CX, 0 ; начальное значение cx=0 ; reset flag: MOV CS:make_minus, 0 next_digit: ; начало цикла ввода ; get char from keyboard ; into AL: MOV AH, 00h ; ввести символ AL с клавиатуры... INT 16h ; and print it: MOV AH, 0Eh ; ... и напечатать его INT 10h ; check for MINUS: CMP AL, '-' ; проверить ввод знака минус JE set_minus ; check for ENTER key: CMP AL, 13 ; carriage return? ; если enter то выход из подпрограммы JNE not_cr JMP stop_input not_cr: CMP AL, 8 ; 'BACKSPACE' pressed? - забой - убрать последнюю цифру JNE backspace_checked MOV DX, 0 ; remove last digit by MOV AX, CX ; division: DIV CS:ten ; AX = DX:AX / 10 (DX-rem). MOV CX, AX PUTC ' ' ; clear position. ; стереть последнюю цифру с дисплея PUTC 8 ; backspace again. JMP next_digit backspace_checked: ; allow only digits: CMP AL, '0' ; это цифра ? JAE ok_AE_0 JMP remove_not_digit ok_AE_0: CMP AL, '9' JBE ok_digit remove_not_digit: PUTC 8 ; backspace. ; это не цифра - стереть символ PUTC ' ' ; clear last entered not digit. PUTC 8 ; backspace again. JMP next_digit ; wait for next input. ok_digit: ; да, это цифра ; multiply CX by 10 (first time the result is zero) ; умножить cx на 10 PUSH AX MOV AX, CX MUL CS:ten ; DX:AX = AX*10 MOV CX, AX POP AX ; check if the number is too big ; (result should be 16 bits) CMP DX, 0 ; если число не влезает в 16 бит, то переход на too_big JNE too_big ; convert from ASCII code: SUB AL, 30h ; преобразовать код символа в цифру ; add AL to CX: ; CX=CX+AX MOV AH, 0 MOV DX, CX ; backup, in case the result will be too big. ADD CX, AX JC too_big2 ; jump if the number is too big. JMP next_digit |
14.01.2023, 13:17 | #2 |
Пользователь
Регистрация: 14.01.2023
Сообщений: 38
|
set_minus:
MOV CS:make_minus, 1 JMP next_digit too_big2: ; отмена, если число слишком большое вариант 2 MOV CX, DX ; restore the backuped value before add. MOV DX, 0 ; DX was zero before backup! too_big: ; отмена, если число слишком большое MOV AX, CX DIV CS:ten ; reverse last DX:AX = AX*10, make AX = DX:AX / 10 MOV CX, AX PUTC 8 ; backspace. ; затереть последнюю цифру PUTC ' ' ; clear last entered digit. PUTC 8 ; backspace again. JMP next_digit ; wait for Enter/Backspace. ; переход к началу цикла ввода stop_input: ; если был введен минус, то изменить знак CX ; check flag: CMP CS:make_minus, 0 JE not_minus NEG CX not_minus: ; всё сделано - выход из подпрограммы POP SI POP AX POP DX RET make_minus DB ? ; used as a flag. флаг "был введён минус" ; печать числа AX со знаком PRINT_NUM: PUSH DX PUSH AX CMP AX, 0 JNZ not_zero PUTC '0' ; если число=0 то просто напечатать "0" и выйти JMP printed2 not_zero: ; the check SIGN of AX, ; make absolute if it's negative: CMP AX, 0 JNS positive NEG AX ; если число отрицательное, то напечатать минус и изменить знак числа PUTC '-' positive: CALL PRINT_NUM_UNS ; вызвать подпрограмму "печать числа без знака" printed2: POP AX POP DX RET ; выход ; печать числа AX без знака PRINT_NUM_UNS: PUSH AX PUSH BX PUSH CX PUSH DX ; flag to prevent printing zeros before number: MOV CX, 1 ; флаг "не печатать нули перед числом" ; (result of "/ 10000" is always less or equal to 9). MOV BX, 10000 ; 2710h - divider. ; делитель=10000 ; AX is zero? CMP AX, 0 JZ print_zero begin_print: ; check divider (if zero go to end_print): CMP BX,0 ; если bx=0 то закончить печать JZ end_print ; avoid printing zeros before number: CMP CX, 0 ; не печатать лидирующие нули JE calc ; if AX<BX then result of DIV will be zero: CMP AX, BX ; если AX<BX то результат деления=0 JB skip calc: MOV CX, 0 ; set flag. MOV DX, 0 DIV BX ; AX = DX:AX / BX (DX=remainder). ; print last digit ; AH is always ZERO, so it's ignored ADD AL, 30h ; convert to ASCII code. PUTC AL ; напечатать очередную цифру MOV AX, DX ; get remainder from last div. ; AX=остаток от последнего деления skip: ; calculate вычислить BX=BX/10 PUSH AX MOV DX, 0 MOV AX, BX DIV CS:ten ; AX = DX:AX / 10 (DX=remainder). MOV BX, AX POP AX JMP begin_print ; переход к началу цикла print_zero: PUTC '0' ; напечатать "0" end_print: ; выход из подпрограммы POP DX POP CX POP BX POP AX RET ten DW 10 ; used as divider. ; константа делитель end start[/CODE] |
14.01.2023, 13:21 | #3 |
Пользователь
Регистрация: 14.01.2023
Сообщений: 38
|
Нужно упростить без подпрогарамм и макрокоманд и процедур.Я пытался корректировать и сокращать прогу,но у меня она по другому не работает.А нужно как-то это всё дело упроститьи сократить,как сказали мне как минимум в половину.Помогите,пожалуйста.
|
14.01.2023, 14:09 | #4 |
Участник клуба
Регистрация: 17.04.2022
Сообщений: 1,833
|
Так используйте вместо процедуры посимвольного ввода цифр числа функцию чтения строки и ее анализ после ввода. Будет гораздо короче.
Код:
|
14.01.2023, 17:11 | #5 |
Пользователь
Регистрация: 14.01.2023
Сообщений: 38
|
Код:
|
14.01.2023, 17:12 | #6 |
Пользователь
Регистрация: 14.01.2023
Сообщений: 38
|
Спасибо.
я тут сделал еще один код попытался .Но там содержимое некоторых меток повторяется.Можно эти метки записать только один раз и после вывода каждого сообщения с просьбой ввести новую переменную переходить к этим метках а потом вводить уже значения переменных?Но сделать это без процедур и макрокоманд.Помогите,пожалуйста? c 'nbv |
14.01.2023, 19:46 | #7 |
Участник клуба
Регистрация: 17.04.2022
Сообщений: 1,833
|
Так расположите переменные перед или после соответствующего Prompt. Тогда позиция переменной будет известна для своего запроса. Достаточно будет сделать цикл с запросами этих переменных по их количеству
Код:
Последний раз редактировалось macomics; 14.01.2023 в 19:55. |
14.01.2023, 20:48 | #8 |
Пользователь
Регистрация: 14.01.2023
Сообщений: 38
|
Спасибо!
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
как сократить код? | Александр121 | Общие вопросы C/C++ | 3 | 02.08.2018 08:50 |
сократить код | Kirja23 | Microsoft Office Excel | 1 | 20.02.2013 22:34 |
Как сократить код | Вадим12091965 | Microsoft Office Excel | 6 | 28.10.2012 11:04 |
Нужно упростить (не сократить) задачу. PascalAbc. | AntoshkaK | Паскаль, Turbo Pascal, PascalABC.NET | 13 | 04.12.2011 02:26 |
Как сократить код DLL | ProgDel | Общие вопросы Delphi | 3 | 16.02.2010 21:12 |