|
|
|
mul |
|
|||
Новичок Профиль Группа: Участник Сообщений: 3 Регистрация: 11.12.2022 Репутация: нет Всего: нет |
; 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 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 Мне сказали,что он вышел у меня слишком огромным и такой код можно написать проще.Помогите,пожалуйста как-то это по-красивому исправить,чтобы код выглядел опрятно |
|||
|
||||
mul |
|
|||
Новичок Профиль Группа: Участник Сообщений: 3 Регистрация: 11.12.2022 Репутация: нет Всего: нет |
Сказали,что ввод вывод сделать без подпрограмм ,и вообще,что не использовать процедуры и макрокоманды.Ну и что сократить код надо в раза 2.Пробовал как-то это дело исправлять.Но при любом моем исправлении прога сразу не работает.Может вы поможете,.Я просто не знаю как код проще и короче таким образом написать
Это сообщение отредактировал(а) mul - 14.1.2023, 13:28 |
|||
|
||||
Правила форума "Asm для начинающих" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Asm для начинающих | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |