Студентам с вопросами о лабораторных работах сюда

Тема в разделе "WASM.BEGINNERS", создана пользователем IceStudent, 11 ноя 2006.

  1. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    Vladimir_B
    Ошибка номер раз: .model tiny предполагает создание com- программы с одним сегментом для кода стека и данных -- у тебя не так, даже obj- файл не создастся поэтому поставь .model small
    Ошибка номер два: замени название метки repeat на reapeat1 -- repeat в masm зарезервированное слово
    А так все работает
    в аттаче твой исправленный исходник и ехе
     
  2. Vladimir_B

    Vladimir_B New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2009
    Сообщения:
    7
    Mikl___
    Спасибо большое. Можно узнать в чем вообще можно сохранить *.exe? Ни в ТАСМ ни в МАСМ у меня не получилось его даже открыть и отредактировать. И как изменить цвет фона и линий?
     
  3. Vladimir_B

    Vladimir_B New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2009
    Сообщения:
    7
    Я сейчас все пишу на форуме, а не читаю статьи, только по той причине, что меня попросили быстро все изменить, а поскольку я плохо соображаю в ассемблере - обратился на форум. Это не лень, заранее спасибо.
     
  4. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    Vladimir_B
    Ты ехе можешь только запустить на выполнение, редактируется файл *.asm а потом компелируется и линкуется в tasm или в masm, похоже, нужно тебе учебник прочитать :)
    Понятно, чукча не читатель -- чукча - писатель. Мало того, что сам не разбаираешься, так имеешь наглость кому-то программу писать.
    Если ты хочешь писать напрямую в видеопамять, то, например, установка точки в режиме 13h сводится к записи кода цвета в видеопамять по адресу, соответствующему адресу точки A=Y*H+X. Ниже приводится программа, рисующая три точки разными цветами в разных местах экрана. Подпрограмма Draw_pixel выводит точку с заданными координатами и с заданным цветом. При вызове данной подпрограммы в регистре BX должна находиться X координата точки, в регистре CL — Y координата, в регистре DL — цвет точки.
    Код (Text):
    1. .286
    2. .model tiny
    3. .code
    4.     ORG 100h
    5. .startup
    6. MOV AH,0Fh  ;запомнить текущий видеорежим
    7.     INT 10h
    8. MOV VIDEOR,AL;видеорежим в переменную videor
    9. MOV AX, 0013h   ;установить видеорежим 13h
    10. INT 10h
    11. PUSH 0A000h ;установить регистр ES на сегмент
    12. POP ES  ;видеопамяти
    13. MOV DI,0    ;Установка точки (0, 0) зеленого цвета
    14. MOV CX,0        ;в левый верхний угол экрана
    15. MOV DL,2
    16. CALL DRAW_PIXEL
    17. MOV DI,160  ;Установка точки (160,100) красного
    18. MOV CX,100  ; цвета в центр экрана
    19. MOV DL,4
    20. CALL DRAW_PIXEL
    21. MOV DI,319  ;Установка точки (319, 199) белого
    22. MOV CX,199  ; цвета в правый нижний угол экрана
    23. MOV DL,7
    24. CALL DRAW_PIXEL
    25. XOR AX,AX       ;ожидание нажатия любой клавиши
    26. INT 16h
    27. MOV AH,0        ;восстановление видеорежима
    28. MOV AL,VIDEOR
    29. INT 10h
    30. ret         ;выход из программы
    31. ;процедура вывода точки на экран
    32. ;DI — X координата точки (от 0 до 319)
    33. ;CX — Y координата точки (от 0 до 199)
    34. ;DL — цвет точки
    35. PROC NEAR DRAW_PIXEL
    36. ;присвоить регистру AX значение горизонтального
    37. ;разрешения
    38. MOV AX,320  ;умножение координаты Y на горизонтальное
    39. MUL CX      ;разрешение. Результат умножения в AX
    40. MOV BX,AX   ;сложить с координатой X
    41. MOV ES:[BX][DI],DL;вывести точку на экран
    42. RET         ;выход из процедуры
    43. ENDP            ;конец процедуры
    44. VIDEOR DB ? ;переменная для хранения значения
    45. ;текущего видеорежима
    46. END         ;конец программы
    На примере этой программы можно выводить на экран различные графики.
     
  5. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    Vladimir_BРисование линей на экране
    Проведение линий подразумевает установку на экране всех точек, принадлежащих отрезку. Сложность при рисовании линии в том, что точки из которых мы ее строим создавали иллюзию прямой. На экране абсолютно точно можно нарисовать только вертикальные, горизонтальные и 1:1 диагональные линии.
    Если у нас установлен 13h графический режим (320x200x256), то горизонтальную линию рисуют следующими командами
    Код (Text):
    1. ;предварительные установки
    2. PUSH 0A000h
    3. POP ES; позиционируем ES на область видеопамяти
    4. MOV DI,X  ; в DI координаты начальной точки по X
    5. MOV AX,320; длина строки экрана
    6. MUL Y; умножаем на Y
    7. ADD DI,AX; и складываем с X
    8. MOV AL,COLOR; цвет линии
    9. ; рисуем горизонтальную линию
    10. MOV CX,N; длина линии
    11. REP STOSB
    Вертикальную линию обычно рисуют циклом
    Код (Text):
    1. MOV CX,N; длина линии
    2. A1: MOV ES:[DI],AL; рисуем точку на строке
    3. ADD DI,320; переход на следующую строку
    4. LOOP A1
    диагональную линию с наклоном влево можно нарисовать циклом
    MOV CX,N; длина линии
    Код (Text):
    1. A1: MOV ES:[DI],AL; рисуем точку на строке
    2. ADD DI,319; переход на следующую строку
    3. LOOP A1
    диагональную линию с наклоном вправо — циклом
    Код (Text):
    1. MOV CX,N; длина линии
    2. A1: MOV ES:[DI],AL; рисуем точку на строке
    3. ADD DI,321; переход на следующую строку
    4. LOOP A1
     
  6. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    Vladimir_B программа выводит на экран окружность, заданного радиуса и цвета, с центром, определенным координатами (R, R) без всякого сопроцессора
    Код (Text):
    1. .286
    2. .model tiny
    3. .code
    4. ORG 100h
    5.  
    6. RADIUS EQU 99   ;рисуем окружность с радиусом 99
    7. RADIUS2 EQU RADIUS*RADIUS   ;квадрат радиуса
    8. DIAMETR EQU RADIUS*2        ;диаметр окружности
    9. N EQU 157*RADIUS/200;количество точек на 1/8
    10. COLOR EQU 10            ;цвет окружности
    11. start: MOV AH,0Fh   ;узнать номер текущего видеорежима
    12. INT 10h
    13. MOV VIDEOR,AL       ;запомним текущий видеорежим
    14. MOV AX,13h;установить видеорежим 320х200х256
    15. INT 10h
    16. PUSH 0A000h;установить регистр ES на сегмент
    17. POP ES          ; видеопамяти
    18. XOR BP,BP           ;будем увеличивать X и Y
    19. MOV Y,RADIUS-1      ;координаты X=0 и Y=R
    20.  CALL DRAW_OCT1 ;рисуем восьмушку окружности
    21. MOV BP,RADIUS-1 ;координата X=2*R
    22. MOV Y,0         ;координата Y=0
    23. CALL DRAW_OCT2  ;рисуем восьмушку окружности
    24. NEG DELTA_X     ;увеличиваем Y и уменьшаем X
    25. MOV Y,RADIUS         
    26. MOV BP,DIAMETR  ;координаты Y=R и X=2*R
    27. CALL DRAW_OCT1  ;рисуем восьмушку окружности
    28. MOV BP,RADIUS       ;координата X=R
    29. MOV Y,0         ;координата Y=0
    30. CALL DRAW_OCT2  ;рисуем восьмушку окружности
    31. NEG DELTA_Y ;уменьшаем координаты Y и X
    32. MOV Y,RADIUS        ;координата Y=R
    33. MOV BP,DIAMETR  ;координата X=2*R
    34. CALL DRAW_OCT1  ;рисуем восьмушку окружности
    35. MOV BP,RADIUS       ;координата X=R
    36. MOV Y,DIAMETR       ;координата Y=2*R
    37. CALL DRAW_OCT2  ;рисуем восьмушку окружности
    38. NEG DELTA_X ; уменьшаем Y и увеличиваем X
    39. XOR BP,BP           ;координата X=0
    40. MOV Y,RADIUS        ;координата Y=R
    41. CALL DRAW_OCT1  ;рисуем восьмушку окружности
    42. MOV BP,RADIUS       ;координата X=R
    43. MOV Y,DIAMETR       ;координата Y=2*R
    44. CALL DRAW_OCT2  ;рисуем восьмушку окружности
    45. XOR AX,AX       ;ожидание нажатия любой клавиши
    46. INT 16h
    47. MOV AX,WORD PTR VIDEOR;восстановление видеорежима
    48. INT 10h
    49. RET                 ;выход из программы
    50. PROC DELTA_CALC ;рассчитаем ошибку накопления
    51. MOV BX,AX   ;в AX значение координаты X или Y
    52. DEC AX          ;вычислим (Y+0,5)2  Y2+Y
    53. MUL AX          ;или (X+0,5)2  X2+X
    54. ADD AX,BX
    55. MOV DELTA,AX    ;и поместим это значение в DELTA
    56. RET
    57. ENDP
    58. ;процедура прорисовки 1/8 окружности с вычислением
    59. PROC DRAW_OCT1  ; координаты X
    60. MOV AX,Y
    61. SHL AX,6     ;должно быть DI=Y*320, но для умножения
    62.     MOV DI,AX   ;на 320 используем сдвиги, AX= Y*64,
    63.     SHL AX,2    ;сохраним AX в DI и умножим Y*64 на 4
    64. ADD DI,AX       ;DI=Y*(256+64)=Y*320.
    65. MOV AX,BP            
    66. SUB AX,RADIUS       ;BP=X AX=R-X
    67. CALL DELTA_CALC ;расчет ошибки накопления по X
    68. MOV CX,N
    69. CIRC1: MOV AX,Y
    70. SUB AX,RADIUS       ;AX=Y-R
    71. MUL AX
    72. NEG AX
    73. ADD AX,RADIUS2  ;AX=R2-Y2
    74. CMP DELTA,AX    ;сравнить текущий X2=R2-Y2 с ошибкой
    75. JBE A3  ;накопления, если меньше, увеличиваем или
    76. ADD BP,DELTA_X;уменьшаем только Y, иначе
    77. MOV AX,BP;увеличиваем или уменьшаем еще и X и
    78. SUB AX,RADIUS; вычисляем новую ошибку накопления
    79. CALL DELTA_CALC
    80. A3: CMP DELTA_Y,1
    81. JNE A1
    82. ADD DI,320
    83. JMP SHORT A2
    84. A1: SUB DI,320
    85. A2: MOV BYTE PTR ES:[DI][BP],COLOR;выводим точку на
    86. MOV AX,DELTA_Y; экран
    87. ADD Y,AX
    88. LOOP CIRC1  ;повторяем цикл
    89. RET
    90. ENDP
    91. ;процедура прорисовки 1/8 окружности с вычислением
    92. PROC DRAW_OCT2  ; координаты X
    93. MOV AX,Y
    94. SHL AX,6     ;должно быть DI=Y*320, но для умножения
    95.     MOV DI,AX   ;на 320 используем сдвиги, AX= Y*64,
    96.     SHL AX,2    ;сохраним AX в DI и умножим Y*64 на 4
    97. ADD DI,AX       ;DI=Y*(256+64)=Y*320.
    98. MOV AX, Y          
    99. SUB AX,RADIUS
    100. CALL DELTA_CALC
    101. MOV CX,N
    102. CIRC2: MOV AX,BP
    103. SUB AX,RADIUS
    104. MUL AX
    105. NEG AX
    106. ADD AX,RADIUS2  ;AX=R2-(X-R)2
    107. CMP DELTA,AX
    108. JBE A5
    109. MOV AX,DELTA_Y
    110. ADD Y,AX
    111. MOV AX,Y
    112. SUB AX,RADIUS
    113. CALL DELTA_CALC
    114. CMP DELTA_Y,1
    115. JNE A4
    116. ADD DI,320
    117. JMP SHORT A5
    118. A4: SUB DI,320
    119. A5: ADD BP,DELTA_X
    120. MOV BYTE PTR ES:[DI][BP],COLOR
    121. LOOP CIRC2
    122. RET
    123. ENDP
    124. VIDEOR DB 0,0   ;значение текущего видеорежима
    125. DELTA   DW  0   ;ошибка накопления
    126. DELTA_X DW  1   ;смещение по оси X
    127. DELTA_Y DW  1   ;смещение по оси Y
    128. Y   DW  0       ;координата Y
    129. END start
     
  7. Vladimir_B

    Vladimir_B New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2009
    Сообщения:
    7
    Я попросил прощения и объяснил ситуацию. Благодарю за удиленное внимание. Я не программист ассемблер, а всего лишь прочитал пару статей и написал пару примитивных программ, поэтому Писать (большая буква имеет значение) я в нем и не умею. А все, что касается моей области я знаю и никогда не спрашиваю, как сделать и подсказать и объяснить всегда готов, даже людям, которые ничего не смыслят :) Если Вас чем-то оскорбляет моя просьба, извиняюсь, тем более неуважение к программистам ассемблера и к Вам лично я не проявлял и на личности не переходил (в отличии от Вас). Если Вы считаете себя настолько гордым, что написать ответ на вопрос о помощи для Вас оскорбление - могли бы не писать, а если написали не стоит проявлять неуважение к человеку.
    Еще раз спасибо Вам, за уделенное внимание.
     
  8. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    Vladimir_B
    Ну и чему мы обиделись? -- если ты студент и в данный момент сидишь на экзамене (ветка называется Студентам с вопросами о лабораторных работах сюда), и то, что написано выше -- это попытка объяснить за пять минут, то что по идее должен знать (но почемуто не знаешь) пытаясь программировать грфические примитивы под DOS. Если это не так -- тогда обясни, почему такой лимит по времени?
     
  9. Vladimir_B

    Vladimir_B New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2009
    Сообщения:
    7
    Я не студент. И дело не в обидах, а в элементарном уважении. Я действующий программист. Только моя область деятельности не связана с низкоуровневым программированием. Ограничение по времени связано с тем, что меня попросили посмотреть и по возможности исправить программу на ассемблере до назначенного времени. Поэтому я и обратился на форум, было бы у меня времени больше, я бы сам сделал. Поскольку это и есть лабораторная работа, я решил опубликовать просьбу именно в этом разделе.
     
  10. RadASM

    RadASM New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2008
    Сообщения:
    12
    Вопрос: будет ли такая программа работать в windows

    я уже написал прогу, но не ясно толи её надо проверять не из под win (если dos то как?), толи она не работает.
     
  11. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Vladimir_B
    А на чём Вы программируете, если не знаете что такое .exe? Скриптовые языки, веб?
     
  12. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    Прерывание 10h -- функция 0Ch -- записать графический пиксел
    содержимое регистров при вызове функции: AH=0Ch, BH= номер страницы
    AL= цвет пикселя (если бит 7 установлен, выполняется операция XOR с цветом экрана)
    CX= столбец, DX= стока
    в твоем случае ищешь фрагмент
    mov ax,0c0fh
    . . .
    int 10h
    содержимое AX -- 0C - номер функции, 0Fh - цвет
    0F нужно поменять в зависимости от желаемого цвета точки на 00 - черный, 01 - синий, 02 - зеленый, 03 - голубой, 04 - красный, 05 - фиолетовый, 06 - желтый, 07 - белый
    Для изменения фона требуется предварительно вызвать функцию 0Bh прерывания 10h
    регистры при вызове AH=0Bh BH=00 BL= цвет фона/цвет бордюра в текстовом режиме:
    00 - черный, 01 - синий, 02 - зеленый, 03 - голубой, 04 - красный, 05 - фиолетовый, 06 - желтый, 07 - белый
     
  13. Vladimir_B

    Vladimir_B New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2009
    Сообщения:
    7
    А с чего Вы взяли, что я не имею представления, что такое ехе? Я писал, что не могу создать ехе-файл из написанного кода ассемблер, в МАСМ'е и в ТАСМ'е. Пишу запросы на SQL, на Visual C++, если это имеет какое-то значение, то еще пишу на 1С. Вообщем кругозор у меня широкий, к ассемблеру, в качестве увлечения, я тоже проявляю внимание по возможности. Если я не так выразился, по поводу ехе в своих постах, виноват, исправлюсь.
     
  14. Vladimir_B

    Vladimir_B New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2009
    Сообщения:
    7
    Mikl___
    Спасибо, я Вам очень признателен. Из написанного Вами и Ваших объяснений, я вынес пользу для себя.
    Еще раз благодарю за внимание.
     
  15. verdizela

    verdizela New Member

    Публикаций:
    0
    Регистрация:
    21 янв 2009
    Сообщения:
    9
    Добрый день.
    Я решил эту проблему другим способом:
    когда длинна значения после процедуры генерации у меня получилась 5
    Код (Text):
    1. cmp bl,5
    2. jz L0035 ; отправляем на новый цыкл
    А новый цыкл начинаем с:
    Код (Text):
    1. L0035:
    2. mov ecx,2Dh
    3. mov byte ptr [ebx+serial],CL   ;добавляем "-"
    4. XOR cl,cl
    5. INC EBX
    6.  
    7. jmp L0040  ; и прыгаем на новый цикл
    8.  ret
    И уже начинаем с:
    Код (Text):
    1. MOV DL,BYTE PTR [EBX-1+szName]
    И таким образом получаем вид "12345-678"
    Спасибо всем, вопрос снят.
     
  16. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    попробуй mov byte ptr [ebx+serial] заменить на xchg byte ptr [ebx+serial-3], прогнать эту команду 3 раза, увеличивая ebx и затем отнять от ebx 3
     
  17. verdizela

    verdizela New Member

    Публикаций:
    0
    Регистрация:
    21 янв 2009
    Сообщения:
    9
    max7C4
    Спасибо за ответ, но таким способом не получилось.
    Я решил эту проблему другим способом:
    когда длинна значения после процедуры генерации у меня получилась 5
    Код (Text):
    1. cmp bl,5
    2. jz L0035 ; отправляем на новый цыкл
    А новый цыкл начинаем с:
    Код (Text):
    1. L0035:
    2. mov ecx,2Dh
    3. mov byte ptr [ebx+serial],CL   ;добавляем "-"
    4. XOR cl,cl
    5. INC EBX
    6.  
    7. jmp L0040  ; и прыгаем на новый цикл
    8.  ret
    И уже начинаем с:
    Код (Text):
    1. MOV DL,BYTE PTR [EBX-1+szName]
    И таким образом получаем вид "12345-678"
    Спасибо всем, вопрос снят.
     
  18. dave101ua

    dave101ua New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2009
    Сообщения:
    6
    Всем спасибо за помщь ! Отличный форум !
     
  19. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    dave101ua
    Oo - это был пост от 2009-01-08 22:10:15! Уже 3 недели прошло!
     
  20. angrylion

    angrylion New Member

    Публикаций:
    0
    Регистрация:
    1 май 2007
    Сообщения:
    10
    Задали на Си написать эквиваленты ADD и SUB с 8-битн. операндами с вычислением CF и OF, используя только присвоение и побитовые операции. С ADD вроде разобрался:

    Код (Text):
    1. #define addround(x) {                   \
    2.     bit1=(num1 >> x)&1;             \
    3.     bit2=(num2 >> x)&1;             \
    4.     sum|=((bit1 ^ bit2) ^ carry)<<x;            \
    5.     carry=(bit1 & bit2)|(bit1 & carry)|(bit2 & carry);  \
    6. }
    7.  
    8. carry=0; overflow=0;
    9. addround(0);
    10. addround(1);
    11. addround(2);
    12. addround(3);
    13. addround(4);
    14. addround(5);
    15. addround(6);
    16. carryintosignbit=carry;
    17. addround(7);
    18. overflow=carry^carryintosignbit;
    Для SUB написал только вычисление результата:
    Код (Text):
    1. carry=1; overflow=0;
    2. num2=(~num2)&0xff;
    3. addround(0);
    4. addround(1);
    5. addround(2);
    6. addround(3);
    7. addround(4);
    8. addround(5);
    9. addround(6);
    10. addround(7);
    Вопрос: как вычислить флаги в SUB? Другой вопрос: неужели процессор вправду устанавливает CF перед началом выполнения SUB?
    Извините за ламерские вопросы.