Возможно ли сократить код? А так же вывести периметр и площадь

Низкоуровневое программирование портов, микроконтроллеров и т.д.

Модератор: Andy

Oxidous
Сообщения: 15
Зарегистрирован: 24 сен 2015, 13:53

26 дек 2015, 15:15

somewhere писал(а):потому что нет у процессора инструкции PUTC. Это макрос, его надо найти в том же файле.

Благодарю за ответ :) Да,это ж ведь тоже макрос,который вынести нужно,но решил проблему иным способом :) Всё работает так, как нужно :)
Только не могу понять,почему не выводит значения периметра и площади прямоугольника в сообщении
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

26 дек 2015, 22:08

Потому что нигде в коде таких инструкций нет. Есть вывод сообщений о площади и периметре, но сами значения нигде не выводятся.
Могу помочь процедуркой вывода на печать:

Код: Выделить всё

; ================================= Печать чисел
; EAX - Число от 0 до 2^32
; Data 0
; Code 68

WriteNumber proc
pushad
mov ebx,10
xor cx,cx
wnum_1:
xor edx,edx
div ebx
push edx
inc cx
or eax,eax
jnz wnum_1
wnum_2:
pop edx
add dl,30h
mov ah,2
int 21h
loop wnum_2
popad
ret
WriteNumber endp
Ее несложно переделать для 16-разрядных чисел и регистров.
И еще: делить на числа, которые являются степенями двойки с помощью DIV - это все равно что трогаться с 5-ой передачи. Используйте SHR. И код проще станет и вам дополнительные баллы обеспечены.
It's a long way to the top if you wanna rock'n'roll
Oxidous
Сообщения: 15
Зарегистрирован: 24 сен 2015, 13:53

27 дек 2015, 22:31

Вот, выкладываю код, может кому пригодится:

Код: Выделить всё

org 100h
    ; приветствие
    mov dx, offset msg1
    mov ah, 9
    int 21h  
    call MY_SCAN_NUM        
    ; очистка экрана
    call CLEAR_SCREEN
 
    ; вывод значений
    mov dx, offset msg2
    mov ah, 9
    int 21h
    call MY_SCAN_NUM
 
    mov xkord, cx
 
    call CLEAR_SCREEN
 
    mov dx, offset msg3
    mov ah, 9
    int 21h
    call MY_SCAN_NUM
 
    mov ykord, cx
 
    call CLEAR_SCREEN
 
    mov dx, offset msg4
    mov ah, 9
    int 21h
    call MY_SCAN_NUM
 
    mov shirina, cx
 
 
    call CLEAR_SCREEN
 
    mov dx, offset msg5
    mov ah, 9
    int 21h
    call MY_SCAN_NUM
 
    mov dlina, cx
 
    ; вычисляем площадь и периметр прямоугольника          
    ; площадь прямоугольника
    mov ax, dlina
    mul shirina
    mov plosiad, ax
 
    ; периметр прямоугольника
    mov bx, shirina
    add bx, dlina
    add bx, bx
    mov perimetr, bx
 
    call CLEAR_SCREEN
 
    mov dx, offset msg6
    mov ah, 9
    int 21h
    mov AX, plosiad  
    call vivod_cisla
 
    mov dx, offset msg7
    mov ah, 9
    int 21h
    mov AX, perimetr
    call vivod_cisla
 
    mov dx, offset msg8
    mov ah, 9
    int 21h
 
    mov ah, 0
    int 16h
 
    ; находим правый верхний угол прямоугольника
    mov ax, xkord
    mov bl, 2
    div bl
    mov b.[xkord], al
 
    mov ax, ykord
    mov bl, 2
    div bl
    mov b.[ykord], al
 
    ; выставляем видео режим 640x480, 16 цветов
    mov al, 12h    
    mov ah, 0
    int 10h
 
    mov cx, xkord
    mov dx, ykord
 
    mov bx,dlina
    add bx,xkord
    mov p1, bx
 
    ; чертим верхнюю линию
    mov al, 50  
 
    VerhLinia:
 
    mov ah, 0ch
    int 10h
 
    inc cx
 
    cmp cx,p1
 
    JNAE VerhLinia
 
    mov cx, xkord
    mov dx, ykord
 
    mov bx, ykord
    add bx, shirina
    mov p2, bx
 
    ; чертим левую линию
 
    LevLinia:
 
 
    mov ah,0ch
    ; левая линия фиолетового цвета
    mov al, 5
    int 10h
 
    inc dx
 
    cmp dx,p2
 
    JNAE LevLinia
 
    mov bx, cx
    add bx, dlina
    mov p3, bx
 
    ; чертим нижнюю линию
 
    NiznLinia:
 
 
    mov ah,0ch  
    ; нижняя линия красного цвета
    mov al, 4
    int 10h
 
    inc cx
 
    cmp cx,p3
 
    JNAE NiznLinia
 
    mov bx,ykord
    mov p4, bx      
 
    ; чертим правую линию
 
    PravLinia:
 
 
    mov ah,0ch  
    ; правая линия голубого цвета
    mov al, 3
    int 10h
 
    dec dx
 
    cmp dx,p4
 
    JNB PravLinia
 
    ret    
    MY_SCAN_NUM PROC NEAR
     mov AH, 2
     mov DL, '>'    ; приглашение
     int 21h ; выводим приглашение
     xor DI, DI     ; итоговое число, - пока ноль
    my_input:
     mov AH, 8      ; ввод символа без показа
     int 21h
     cmp AL, 13     ; Enter нажали ?
     je Oxid_vihod  ; да - уходим
     cmp AL, '9'
     ja my_input    ; какую-то бОльшую букву ввели - игнорируем
     cmp AL, '0'
     jb my_input    ; какую-то меньшую букву ввели - игнорируем
 
     mov AH, 2
     mov DL, AL     ; цифра
     int 21h        ; выводим цифру
     sub AL, '0'    ; преобразуем символ в число 0..9
     xor AH, AH     ; AH = 0
     mov CX, AX     ; цифра теперь в CX
     mov AX, DI     ; в AX наш итог
     mov BX, 10     ; десятичная у нас система ввода
     mul BX         ; AX = AX*10
     add AX, CX     ; добавим нашу цифру
     mov DI, AX     ; результат в DI
     jmp my_input   ; на следующую цифру
    Oxid_vihod:
     mov CX, DI     ; запишем результат
     RET ; валим
    MY_SCAN_NUM ENDP
;------------
 
; процедура CLEAR_SCREEN
    CLEAR_SCREEN PROC NEAR
    PUSH    AX      ; store registers...
    PUSH    DS      ;
    PUSH    BX      ;
    PUSH    CX      ;
    PUSH    DI      ;
 
    MOV     AX, 40h
    MOV     DS, AX  ; for getting screen parameters.
    MOV     AH, 06h ; scroll up function id.
    MOV     AL, 0   ; scroll all lines!
    MOV     BH, 07  ; attribute for new lines.
    MOV     CH, 0   ; upper row.
    MOV     CL, 0   ; upper col.
    MOV     DI, 84h ; rows on screen -1,
    MOV     DH, [DI] ; lower row (byte).
    MOV     DI, 4Ah ; columns on screen,
    MOV     DL, [DI]
    DEC     DL      ; lower col.
    INT     10h
 
    ; set cursor position to top
    ; of the screen:
    MOV     BH, 0   ; current page.
    MOV     DL, 0   ; col.
    MOV     DH, 0   ; row.
    MOV     AH, 02
    INT     10h
 
    POP     DI      ; re-store registers...
    POP     CX      ;
    POP     BX      ;
    POP     DS      ;
    POP     AX      ;
 
    RET
    CLEAR_SCREEN ENDP
 
Oxidous
Сообщения: 15
Зарегистрирован: 24 сен 2015, 13:53

27 дек 2015, 22:32

Продолжение:

Код: Выделить всё

vivod_cisla proc
 
xor cx, cx
mov bx, 10
oi2:
xor dx,dx
div bx
push dx
inc  cx
test ax, ax
jnz oi2
mov ah, 02h
oi3:
pop dx
add dl, '0'
int 21h
loop oi3
 
ret
 
vivod_cisla endp
 
    dlina dw 0
    shirina dw 0
    xkord dw 0
    ykord dw 0
    plosiad dw 0
    perimetr dw 0  
    msg1 db 'Pogrammu napisal: Imia Familija. Nazmite <Enter> ', '$'
    msg2 db 'Vvedite X koordinatu centra priamougolnika: ', '$'
    msg3 db 'Vvedite Y koordinatu centra priamougolnika: ', '$'
    msg4 db 'Vvedite shirinu priamougolnika (max 480): ', '$'
    msg5 db 'Vvedite dlinu priamougolnika (max 640): ', '$'
    msg6 db 'Plosiad Vashego priamougolnika: ', '$'
    msg7 db 'Perimetr vashego priamougolnika: ', '$'
    msg8 db 'Dlia sozdanija priamougolnika nazmite <ENTER>', '$'
 
    p1 dw 0 ;конец верхней линии x
    p2 dw 0 ;конец левой линии y
    p3 dw 0 ;конец нижней линии x
    p4 dw 0 ;конец правой линии y
 
    end
Есть ещё одно задание:

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

Как бы код, который я вылодил, переделать под 2 вариант?
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

28 дек 2015, 16:04

А чем этот вариант отличается от того, что было в твоей задаче?
It's a long way to the top if you wanna rock'n'roll
Oxidous
Сообщения: 15
Зарегистрирован: 24 сен 2015, 13:53

28 дек 2015, 20:35

Отличается он тем,что здесь вводить координаты нужно. Я имею ввиду,что тогда иначе считается периметр, да и сам прямоугольник строится тоже иначе :)
Допустим, если координаты первого угла 10х10, а второго 20х20, то должен строится квадрат со сторонами, длины которых равны 10 см, ибо второй угол находится в 10 пиксклях по оси х и оси y от первого угла. А сейчас получается, что строится со сторонами 20 см :)

Тема больше не актуальна. Со всем разобрался. Благодарю за помощь :)
Ответить