Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.12.2015, 08:41   #1
Oxidous
Пользователь
 
Регистрация: 31.08.2007
Сообщений: 28
По умолчанию Возможно ли сократить код? А так же вывести периметр и площадь

Всем доброго времени суток,

Задание такое (делается в emu8086): Пользователь вводит координаты левого верхнего (x1, y1) и правого нижнего (x2, y2) углов прямоугольника. Программа должна нарисовать прямоугольник на экране и вывести его периметр (P) и площадь (S).
Примечание: Для ввода/вывода использовать прерывания (INT). Не использовать никакие команды "emu, macro" и т.п.

Вот код:

Код:
include 'emu8086.inc'
org 100h 
 
jmp kod
 
dannie:
 
 
 
dlina dw 0
sirina dw 0
xkord dw 0
ykord dw 0
plosiad dw 0
perimetr dw 0
msg1 db 'Vvedite x koordinatu centra priamougolnika:', '$'
msg2 db 'Vvedite y koordinatu centra priamougolnika:', '$'
msg3 db 'Vvedite sirinu priamougolnika:', '$'
msg4 db 'Vvedite dlinu priamougolnika:', '$'
msg5 db 'Plosiad Vasego priamougolnika ravna: ', '$'
msg6 db 'Dlina Vashego priamougolnika ravna: ', '$'
msg7 db 'Certim? (Nazmite liubuiu klavishu)', '$'
 
 
p1 dw 0 ;x konec verhnei linii
p2 dw 0 ;y konec levoi linii
p3 dw 0 ;x konec niznei linii
p4 dw 0 ;y konec pravoi linii
 
 
kod:
;--vivodim znacenia
mov dx, offset msg1
mov ah, 9
int 21h
call scan_num
 
mov xkord, cx
 
call CLEAR_SCREEN
 
mov dx, offset msg2
mov ah, 9
int 21h
call scan_num
 
mov ykord, cx
 
call CLEAR_SCREEN
 
mov dx, offset msg3
mov ah, 9
int 21h
call scan_num
 
mov sirina, cx
 
 
call CLEAR_SCREEN
 
mov dx, offset msg4
mov ah, 9
int 21h
call scan_num
 
mov dlina, cx
 
 
;--
 
;--scitaem plosiad i perimetr
mov al, b.[dlina]
mov bl, b.[sirina]
mul bl
mov plosiad, ax
 
mov bx, 0
add bx, sirina
add bx, sirina
add bx, dlina
add bx, dlina
mov perimetr, bx
 
call CLEAR_SCREEN
 
mov dx, offset msg5
mov ah, 9
int 21h
 
mov dx, offset msg6
mov ah, 9
int 21h
 
mov dx, offset msg7
mov ah, 9
int 21h
 
mov ah, 0
int 16h
 
;--nahodim verhniy praviy ugol priamogugolnika 
mov ax, xkord
mov bl, 2
div bl
mov b.[xkord], al
 
mov ax, ykord
mov bl, 2
div bl
mov b.[ykord], al
;--
 
 
;--vistavliaem video rezim  320x200, 256 cvetov
mov al, 13h
mov ah, 0
int 10h
;--
 
mov cx, xkord
mov dx, ykord
 
mov bx,dlina
add bx,xkord
mov p1, bx
 
 
;--certim verhniuiu liniu
mov al, 50
verhniaiaLinia:
 
 
 
mov ah, 0ch
int 10h
 
inc cx
 
cmp cx,p1
 
JNAE verhniaiaLinia
;--
 
mov cx, xkord
mov dx, ykord
 
mov bx, ykord
add bx, sirina
mov p2, bx
 
;--certim levuiu liniu
 
levaiaLinia:
 
 
mov ah,0ch
int 10h
 
inc dx
 
cmp dx,p2
 
JNAE levaiaLinia
 
;--
mov bx, cx
add bx, dlina
mov p3, bx
 
;--certim nizniuiu liniu
 
nizniaiaLinia :
 
 
mov ah,0ch
int 10h
 
inc cx
 
cmp cx,p3
 
JNAE nizniaiaLinia 
 
;--
mov bx,ykord
mov p4, bx
;--certim pravuiu liniu
 
pravaiaLinia:
 
 
mov ah,0ch
int 10h
 
dec dx
 
cmp dx,p4
 
JNB pravaiaLinia 
 
ret
 
DEFINE_SCAN_NUM
DEFINE_CLEAR_SCREEN
end
1. По заданным координатам прямоугольник чертится, с этим проблем нет, но почему-то не выводятся площадь и периметр,хотя, вроде как, должны.
2. Можно ли сократить код? Ибо преподу может не понравится такой длинный код.

Заранее благодарю за оказанную помощь.
Oxidous вне форума Ответить с цитированием
Старый 14.12.2015, 12:47   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Я б не сказал что код длинный. Для АСМ это нормально.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 15.12.2015, 09:35   #3
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

Код:
mov bx, 0
add bx, sirina
add bx, sirina
add bx, dlina
add bx, dlina
вполне можно заменить на
Код:
mov bx, sirina
add bx, dlina
add bx, bx
вместо
Код:
jmp kod
 
dannie:
 
 
 
dlina dw 0
sirina dw 0
xkord dw 0
ykord dw 0
plosiad dw 0
perimetr dw 0
msg1 db 'Vvedite x koordinatu centra priamougolnika:', '$'
msg2 db 'Vvedite y koordinatu centra priamougolnika:', '$'
msg3 db 'Vvedite sirinu priamougolnika:', '$'
msg4 db 'Vvedite dlinu priamougolnika:', '$'
msg5 db 'Plosiad Vasego priamougolnika ravna: ', '$'
msg6 db 'Dlina Vashego priamougolnika ravna: ', '$'
msg7 db 'Certim? (Nazmite liubuiu klavishu)', '$' 
p1 dw 0 ;x konec verhnei linii
p2 dw 0 ;y konec levoi linii
p3 dw 0 ;x konec niznei linii
p4 dw 0 ;y konec pravoi linii 
kod:
вполне можно поместить данные в конец программы за команду ret
Код:
ret 
 
dlina dw 0
sirina dw 0
xkord dw 0
ykord dw 0
plosiad dw 0
perimetr dw 0
msg1 db 'Vvedite x koordinatu centra priamougolnika:', '$'
msg2 db 'Vvedite y koordinatu centra priamougolnika:', '$'
msg3 db 'Vvedite sirinu priamougolnika:', '$'
msg4 db 'Vvedite dlinu priamougolnika:', '$'
msg5 db 'Plosiad Vasego priamougolnika ravna: ', '$'
msg6 db 'Dlina Vashego priamougolnika ravna: ', '$'
msg7 db 'Certim? (Nazmite liubuiu klavishu)', '$' 
p1 dw 0 ;x konec verhnei linii
p2 dw 0 ;y konec levoi linii
p3 dw 0 ;x konec niznei linii
p4 dw 0 ;y konec pravoi linii

Последний раз редактировалось Mikl___; 15.12.2015 в 09:38.
Mikl___ вне форума Ответить с цитированием
Старый 18.12.2015, 13:29   #4
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

..выводить графику функцией 0Сh можно только в качестве примера. Оттрасируй её в отладчике и посмотри за сколько шагов она выполняется. Она настолько тормознутая, что её практически нигде не используют. Обычно копируют точку прямо в видео/память. Вот тебе код на FASM..

Пример окна:

Код:
Input X  (max 320)..: 120
Input Y  (max 200)..: 50
Width    (max 320)..: 148
Height   (max 200)..: 67
----------------------------
Area     (S)........: 9916
Perimetr (P)........: 430
Вложения
Тип файла: zip Example.zip (1.9 Кб, 10 просмотров)
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 22.12.2015, 09:59   #5
Oxidous
Пользователь
 
Регистрация: 31.08.2007
Сообщений: 28
По умолчанию

Цитата:
Сообщение от Mikl___ Посмотреть сообщение
вполне можно заменить на
Огромное Вам спасибо за помощь

Цитата:
Сообщение от R71MT Посмотреть сообщение
..выводить графику функцией 0Сh можно
Вам так же огромное спасибо за помощь
Пробовал запустить Ваш пример на 8086, но при вводе данных в Х координату, мне выдаёт: "this interrupt is not defined yet, it is availabe for custom functions. You can define this interrupt by modifying interrupt vector table. Refer to the list of supported interrupts and global memory table."
Oxidous вне форума Ответить с цитированием
Старый 23.12.2015, 08:52   #6
Oxidous
Пользователь
 
Регистрация: 31.08.2007
Сообщений: 28
По умолчанию

А можно ли чем то заменить директиву "include emu8086.inc"? Просто препод хочет,чтоб не использовались директивы и всякие команды macro.
Чем тогда можно заменить "call scan_num" и "call CLEAR_SCREEN"? Чтоб убрать из программы emu8086.inc?
Oxidous вне форума Ответить с цитированием
Старый 23.12.2015, 09:32   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

откройте emu8086.inc
и скопируйте оттуда код процедур scan_num и CLEAR_SCREEN
Serge_Bliznykov вне форума Ответить с цитированием
Старый 23.12.2015, 12:06   #8
Oxidous
Пользователь
 
Регистрация: 31.08.2007
Сообщений: 28
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
откройте emu8086.inc
и скопируйте оттуда код процедур scan_num и CLEAR_SCREEN
Я понял, вот две эти процедуры, только вот я не понимаю, как мне их в код закинуть?

SCAN_NUM:

Код:
DEFINE_SCAN_NUM         MACRO
LOCAL make_minus, ten, next_digit, set_minus
LOCAL too_big, backspace_checked, too_big2
LOCAL stop_input, not_minus, skip_proc_scan_num
LOCAL remove_not_digit, ok_AE_0, ok_digit, not_cr

; protect from wrong definition location:
JMP     skip_proc_scan_num

SCAN_NUM        PROC    NEAR
        PUSH    DX
        PUSH    AX
        PUSH    SI
       
        MOV     CX, 0

        ; reset flag:
        MOV     CS:make_minus, 0

next_digit:

        ; get char from keyboard
        ; into AL:
        MOV     AH, 00h
        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?
        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)
        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
        JNE     too_big

        ; convert from ASCII code:
        SUB     AL, 30h

        ; add AL to CX:
        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:
        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:
        ; 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.
ten             DW      10      ; used as multiplier.
SCAN_NUM        ENDP

skip_proc_scan_num:

DEFINE_SCAN_NUM         ENDM
С CLEAR SCREEN разобрался

Последний раз редактировалось Oxidous; 23.12.2015 в 12:09.
Oxidous вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
площадь и периметр треугольника за формулой Герона С++ (консольный режим) программирование Помощь студентам 4 23.01.2014 23:21
Определить периметр и площадь треугольника skoch Общие вопросы C/C++ 6 19.04.2013 00:03
Линейные алгоритмы. Вычислить периметр и площадь треугольника. sqr Паскаль, Turbo Pascal, PascalABC.NET 2 29.10.2011 15:24
описать процедуру вычисляющую периметр и площадь равностороннего треугольника по данной стороне А. Aimet Паскаль, Turbo Pascal, PascalABC.NET 1 18.06.2011 20:04
определить площадь,периметр,биссектрисы и т.п. треугольника Иоанн IV Грозный Помощь студентам 2 16.01.2011 20:12