На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Помните, что у нас есть FAQ раздела Assembler и Полезные ссылки. Посмотрите, возможно, там уже имеется решение вашего вопроса.

3. Настоятельно рекомендуем обратить особое внимание на правила форума, которые нарушаются чаще всего:
  3.1. Заголовок темы должен кратко отражать её суть. Темы с заголовками типа "Срочно помогите!" или "Ассемблер" будут отправляться в Корзину для мусора.
  3.2. Исходники программ обязательно выделяйте тегами [code]...[/code] (одиночные инструкции можно не выделять).
  3.3. Нежелательно поднимать старые темы (не обновлявшиеся более года) без веской на то причины.

Не забывайте также про главные Правила форума!

Добро пожаловать и приятного вам общения!!! ;)
 
Модераторы: Jin X, Qraizer
Страницы: (2) 1 [2]  все  ( Перейти к последнему сообщению )  
> Возможно ли сократить код? А так же вывести периметр и площадь , сократить код
    Славян Благодарю за подсказку :)

    Кстати, Ваш код у меня не работает (я говорю о Вашем выложенном варианте), видать компиляторы разные и следовательно программа работает некорректно :)

    А подойдёт ли данный код (я о выводе целого знакового числа от 0 до 99) для моей программы? Ведь периметр считается по формуле: P = 2 * (a + b), а следовательно периметр может быть и трёхзначным числом, или здесь это не имеет значения?

    Так, вот по Вашей подсказке сделал:

    ExpandedWrap disabled
       OutInt proc
       aam
       add ax,3030h
       mov dl,ah
       mov dh,al
       mov ah,02
       int 21h
       mov dl,dh
       int 21h
       RET
       OutInt endp


    Как мне его, скажем так, привязать к площади и периметру прямоугольника?

    ExpandedWrap disabled
      ; площадь прямоугольника
      mov ax, dlina
      mul shirina
      mov plosiad, ax
       
      ; периметр прямоугольника
      mov bx, shirina
      add bx, dlina
      add bx, bx
      mov perimetr, bx
      Цитата Oxidous @
      Кстати, Ваш код у меня не работает (я говорю о Вашем выложенном варианте), видать компиляторы разные и следовательно программа работает некорректно

      Используй CLEAR_SCREEN. Его код очистки экрана не будет работать на 99.99% машин, так как требует загрузки драйвера ANSI.SYS (драйвер и во времена доса редко кто использовал, т.к. функционал сомнительный, а память кушал дай бох). Ну или компилируй под CP/M, на ней часть функционала этого драйвера вшита непосредственно в систему :)
        Цитата Oxidous @
        Ваш код у меня не работает (я говорю о Вашем выложенном варианте), видать компиляторы разные и следовательно программа работает некорректно
        Возможно, я успешно собирал в DOSBox'е из под tasm'овского Borland C 3.1. :blush:
        Цитата Oxidous @
        Как мне его, скажем так, привязать к площади и периметру прямоугольника?
        Я так сделал:
        ExpandedWrap disabled
            mov   dx, offset msg7
            mov   ah, 9
            int   21h
           
            mov   AX, perimetr    ; можно BX
            call  OutInt
          Славян Огромное Вам спасибо :) Я Вам в PM письмо выслал :)

          Вот, выкладываю готовый код программы:

          ExpandedWrap disabled
                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
             
            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).
          Сообщение отредактировано: Oxidous -
            Ну вот, вроде как переделал задание под 2 вариант. Заменил длину и ширину (вводимые с клавиатуры) на координаты x2kord и y2kord. Быть может кто-нить мог бы проверить, правильно ли я сделал? Ибо прямоугольник чертится и площадь с периметром так же выводятся, но правильно ли я сделал задание?

            ExpandedWrap disabled
              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 x2kord, cx
               
               
                  call CLEAR_SCREEN
               
                  mov dx, offset msg5
                  mov ah, 9
                  int 21h
                  call MY_SCAN_NUM
               
                  mov y2kord, cx
               
                  ; вычисляем площадь и периметр прямоугольника          
                  ; площадь прямоугольника
                  mov ax, y2kord
                  mul x2kord
                  mov plosiad, ax
               
                  ; периметр прямоугольника
                  mov bx, x2kord
                  add bx, y2kord
                  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,y2kord
                  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, x2kord
                  mov p2, bx
               
                  ; чертим левую линию
               
                  LevLinia:
               
               
                  mov ah,0ch
                  ; левая линия фиолетового цвета
                  mov al, 5
                  int 10h
               
                  inc dx
               
                  cmp dx,p2
               
                  JNAE LevLinia
               
                  mov bx, cx
                  add bx, y2kord
                  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
               
              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
               
                  y2kord dw 0
                  x2kord 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 koordinatu x1: ', '$'
                  msg3 db 'Vvedite koordinatu y1: ', '$'
                  msg4 db 'Vvedite koordinatu x2: ', '$'
                  msg5 db 'Vvedite koordinatu y1: ', '$'
                  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
              И ещё такой вопрос по второму варианту задания:

              Периметр и площадь, вроде как, некорректно считаются для второго варианта, а потому нужно, чтоб из координат второй точки вычитались координаты первой точки.
              Допустим, пусть координаты первой точки (x1, y1) будут 10 и 10, а координаты второй точки (x2, y2) 100 и 100. Тогда вычитаем первую точку из второй (100-10 и 100-10), получаем 90 и 90, и уже по этим полученным значениям считаем периметр и площадь по.

              Вот код вводимых координат первой точки:

              ExpandedWrap disabled
                ; вводим значения первой координаты
                ; x1
                mov dx, offset msg2
                mov ah, 9
                int 21h
                call scan_num
                 
                mov xkord, cx
                 
                call clear_screen
                ; y1
                mov dx, offset msg3
                mov ah, 9
                int 21h
                call scan_num
                 
                mov ykord, cx


              ExpandedWrap disabled
                ; вводим значения второй координаты
                ; x2
                mov dx, offset msg4
                mov ah, 9
                int 21h
                call scan_num
                 
                mov x2kord, cx
                 
                call clear_screen
                 
                ; y2
                mov dx, offset msg5
                mov ah, 9
                int 21h
                call scan_num
                 
                mov y2kord, cx


              Вот код периметра и площади прямоугольника:

              ExpandedWrap disabled
                ; периметр прямоугольника
                mov bx, x2kord
                add bx, y2kord
                add bx, bx
                mov perimetr, bx
                 
                ; площадь прямоугольника
                mov ax, y2kord
                mul x2kord
                mov plotas, ax


              Как я понимаю, первые координаты записываются в CX регистр. Как в мне в периметре и площади прямоугольника вычесть из значений второй координаты значения первой координаты?
              Я понимаю, что это делается командой SUB CX, BX, но при работе программы периметр и площаль остаются такими же, как при умножении значений второй координаты для площади(a*b)и 2*(a+b) - для периметра.
                Прошлый, нередактируемый ввод, напрягал, посему переделать лучше в таковой:
                ExpandedWrap disabled
                  MY_SCAN_NUM2 PROC NEAR
                      mov AH, 2
                      mov DL, '>' ; приглашение
                      int 21h ; выводим приглашение
                   
                      mov AH, 03Fh    ; ввод строки
                      mov DX, offset buffer
                      mov CX, 20  ; 20 символов
                      xor BX, BX  ; из клавы читаем
                      int 21h ; ввод строки
                   
                      sub AX, 2   ; <Enter> будет 2 символа занимать?
                      xor SI, SI
                      mov CX, AX  ; сколько символов ввели
                      xor DI, DI  ; итоговое число, - пока ноль
                    LBL_chislo:
                      mov AL, 10
                      mov BL, buffer[SI]
                      sub BL, '0' ; '0'..'9' -> 0..9
                      mul DI  ; AX = DI*10
                      add AX, BX  ; AX = DI*10 + BL
                      inc SI  ; готовимся к следующей цифре
                      mov DI, AX  ; итог - сюда
                    loop LBL_chislo
                      mov CX, DI  ; запишем результат
                      RET ; валим
                  MY_SCAN_NUM2 ENDP
                  ...
                  buffer db 20 dup(?) ; сюда числа вводим


                Добавлено
                Цитата Oxidous @
                Как в мне в периметре и площади прямоугольника вычесть из значений второй координаты значения первой координаты?
                Как-то так у меня вышло:
                ExpandedWrap disabled
                  ; периметр прямоугольника
                      mov bx, y2kord
                      sub bx, ykord
                      jns LBL_otriY
                      neg BX
                   LBL_otriY:
                      mov shirina, BX ; пригодится
                   
                      mov cx, x2kord
                      sub cx, xkord
                      jns LBL_otriX
                      neg CX
                   LBL_otriX:
                      mov dlina, CX   ; пригодится
                      add CX, BX
                      shl CX, 1   ; CX = CX*2
                      mov perimetr, CX
                   
                  ; площадь прямоугольника
                      mov AX, dlina
                      mul BX  ; AX = shirina*AX = shirina*dlina
                      mov plosiad, AX
                  Славян Благодарю :) Пробовал Ваш метод ввода числа - компиляция проходит, а вот при запуске программыв пишет,что не поддерживает (шnput redirection is not supported yet!INT 21h/9h should be used instead. refer to interrupt reference) и программы тупо зависает.

                  2. А для чего длина осталась? Просто я полностью убрал ввод длины и ширины из программы,ибо по заданию 2 варианта её вводить не нужно :)
                  Сообщение отредактировано: Oxidous -
                    Цитата Oxidous @
                    А для чего длина осталась?
                    Да это банально идёт как вспомогательная переменная. :blush:
                    Цитата Oxidous @
                    Пробовал Ваш метод ввода числа - компиляция проходит, а вот при запуске программыв пишет,что не поддерживает (шnput redirection is not supported yet!INT 21h/9h should be used instead. refer to interrupt reference) и программы тупо зависает.
                    Грустно сие. Надо тогда прежний вариант оставить или думать в чём проблема... :unsure:
                      СлавянДа, Вы правы :) Потому оставил прежний вариант :)
                      Ну, преподу прокатило и без вспомогательной переменной, хотя всё равно буду дальше переделывать,чтоб лучше понять и сделать так, как нужно по заданию :)
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0452 ]   [ 15 queries used ]   [ Generated: 16.04.24, 20:22 GMT ]