Компиляция com программы - Assembler

Узнай цену своей работы

Формулировка задачи:

Нашла задачу, рисует линии, как я поняла от точки до точки. С помощью tasm и tlink делаю exe файл, запускается, курсор видно, но линии не рисуются. Прочитала что нужно делать не exe, а COM, но так и не поняла как его делать...
Листинг программы
  1. ; mousedr.asm
  2. ;Рисует на экране прямые линии, оканчивающиеся в позициях, которые указываются мышью.
  3. STACK 256
  4. .model tiny
  5. .code
  6. org 100h ; COM-файл.
  7. .186 ; Для команжы shr cx, 3.
  8. start:
  9. mov ax, 12h
  10. int 10h ; Видеорежим 640*480.
  11. mov ax, 0 ; Инициализировать мышь.
  12. int 33h
  13. mov ax, 1 ; Показать курсор мыши.
  14. int 33h
  15. mov ax, 000Ch ; Установить обработчик событий мыши.
  16. mov cx, 0002h ; Событие - нажатие левой кнопки.
  17. mov dx, offset handler ; ES:DX - адрес обработчика.
  18. int 33h
  19. mov ah, 0 ; Ожидание нажатия любой клавиши.
  20. int 16h
  21. mov ax, 000Ch
  22. mov cx, 0000h ; Удалить обработчик событий мыши.
  23. int 33h
  24. mov ax, 3 ; Текстоый режим.
  25. int 10h
  26. ret ; Конец программы.
  27. ; Обработчик событий мыши: при первом нажатии выводит точку на экран,
  28. ; при каждом дальнейшем вызове проводит прямую линию от предыдущей
  29. ; точки к текущей.
  30. handler:
  31. push 0A000h
  32. pop es ; ES - начало видеопамяти.
  33. push cs
  34. pop ds ; DS - сегмент кода и данных этой программы.
  35. push cx ; CX (X-координата) и DX(Y-координата)
  36. push dx ; потребуются в конце.
  37. mov ax, 2 ; Спрятать курсор мыши перед выводом на экран.
  38. int 33h
  39. cmp word ptr previous_X, -1 ; Если это первый вызов,
  40. je first_point ; только вывести точку.
  41. call line_bresenham ; Иначе - провести прямую.
  42. exit_handler:
  43. pop dx ; Восстановить CX и DX
  44. pop cx
  45. mov previous_X, cx ; и запомнить их как предыдущие
  46. mov previous_Y, dx ; координаты.
  47. mov ax, 1 ; Показать курсор мыши.
  48. int 33h
  49. retf ; Выход из обработчика - команда RETF.
  50. first_point:
  51. call putpixellb ; Вывод одной точки (при первом вызове).
  52. jmp short exit_handler
  53. ; Процедура рисования прямой линии с использованием алгоритма Брезенхама.
  54. ; Вывод CX, DX - X, Y начальной точки.
  55. ; previous_X, previous_Y - X, Y начальной точки.
  56. line_bresenham:
  57. mov ax, cx
  58. sub ax, previous_X ; AX = длина проекции прямой на ось X.
  59. jns dx_pos ; Если AX отрицательный -
  60. neg ax ; сменить его знак, причем
  61. mov word ptr X_increment, 1 ; координата X при выводе
  62. jmp short dx_neg ; прямой будет расти.
  63. dx_pos: mov word ptr X_increment, -1 ; Иначе - уменьшаться.
  64. dx_neg: mov bx, dx
  65. sub bx, previous_Y ; BX = длина проекции прямой на ось Y.
  66. jns dy_pos ; Если BX отрицательный -
  67. neg bx ; сменить его знак, причем
  68. mov word ptr Y_increment, 1 ; координата Y при выводе
  69. jmp short dy_neg ; прямой будет расти.
  70. dy_pos: mov word ptr Y_increment, -1 ; иначе - уменьшаться.
  71. dy_neg:
  72. shl ax, 1 ; Удвоить значения проекций,
  73. shl bx, 1 ; чтобы избежать работы с полуцелыми числами.
  74. call putpixellb ; Вывести первую точку (прямая рисуется от
  75. ; CX, DX к previous_X, previous_Y).
  76. cmp ax, bx ; Если проекция на ось X больше, чем на Y,
  77. jna dx_le_dy
  78. mov di, ax ; DI будет указывать, в какую сторону мы
  79. shr di, 1 ; отклонились от идеальной прямой.
  80. neg di ; Оптимальное начальное значение DI:
  81. add di, bx ; DI = 2 * dy - dx
  82. cycle:
  83. cmp cx, word ptr previous_X ; Основной цикл выполняется,
  84. je exit_bres ; пока X не станет равное previous_X.
  85. cmp di, 0 ; Если DI > 0,
  86. jl fractlt0
  87. add dx, word ptr Y_increment ; перейти к следующему Y
  88. sub di, ax ; и уменьшить DI на 2 * dx.
  89. fractlt0:
  90. add cx, word ptr X_increment ; Следующий X (на каждом шаге).
  91. add di, bx ; Увеличить на DI на 2 * dy.
  92. call putpixellb ; Вывести точку. ;!!!!!
  93. jmp short cycle ; Продолжить цикл.
  94. dx_le_dy: ; Если проекция на ось Y больше, чем на X.
  95. mov di, bx
  96. shr di, 1
  97. neg di ; Оптимальное начальное значение DI:
  98. add di, ax ; DI = 2 * dx - dy.
  99. cycle2:
  100. cmp dx, word ptr previous_Y ; Основной цикл выполняется,
  101. je exit_bres ; пока Y не станет равным previous_Y.
  102. cmp di, 0 ; Если DI > 0,
  103. jl fractlt02
  104. add cx, word ptr X_increment ; перейти к следующему X
  105. sub di, bx ; и уменьшить DI на 2 * dy,
  106. fractlt02:
  107. add dx, word ptr Y_increment ; Следующий Y (на каждом шаге).
  108. add di, ax ; Увеличить DI на 2 * dy,
  109. call putpixellb ; вывести точку,
  110. jmp short cycle2 ; продолжить цикл.
  111. exit_bres:
  112. ret ; Конец процедуры.
  113. ; Процедура вывода точки на экран в режиме, использующем один бит для
  114. ; хранения одного пикселя.
  115. ; DX = строка, CX = столбец.
  116. ; Все регистры сохраняются.
  117. putpixellb:
  118. pusha ; Сохранить регистры.
  119. xor bx, bx
  120. mov ax, dx ; AX = номер строки.
  121. imul ax, ax, 80 ; AX = номер строки x число байтов в строке.
  122. push cx
  123. shr cx, 3 ; CX = номер байта в строке.
  124. add ax, cx ; AX = номер байта в видеопамяти.
  125. mov di, ax ; Поместить его в SI и DI для команд
  126. mov si, di ; строковой обработки.
  127. pop cx ; CX снова содержит номер столбца.
  128. mov bx, 0080h
  129. and cx, 07h ; Последние три бита CX =
  130. ; остаток от деления на 8 = номер бита в байте
  131. ; считая справа налево.
  132. shr bx, cl ; Теперь в BL установлен в 1 нужный бит.
  133. lods es: byte ptr some_label ; AL = байт из видеопамяти.
  134. ;or ax, bx ; Установить выводимый бит в 1,
  135. ; Чтобы стереть пиксел с экрана, эту команду OR можно заменить на
  136. not bx
  137. and ax, bx
  138. ; или лучше инициализировать BX не числом 0080h, а числом FF7Fh и использовать
  139. ; только and
  140. stosb ; И вернуть байт на место.
  141. popa ; Восстановить регистры.
  142. ret ; Конец.
  143. previous_X dw -1 ; Предыдущая X-координата.
  144. previous_Y dw -1 ; Предыдущая Y-координата.
  145. Y_increment dw -1 ; Направление изменения Y.
  146. X_increment dw -1 ; Направление изменения X.
  147. some_label: ; Метка, используемая для переопределения
  148. ; сегмента-источника для lods с DS на ES.
  149. end start
В общем, кто звстречался с проблемой, помогитее

Решение задачи: «Компиляция com программы»

textual
Листинг программы
  1. tasm MyProg.asm
  2. tlink /Tdc MyProg.obj

Объяснение кода листинга программы

  1. tasm: это команда компилятора Assembler, поддерживаемого Borland Turbo Assembler (TASM).
  2. MyProg.asm: это имя исходного файла Assembler, который будет скомпилирован.
  3. tlink: это команда линковщика для создания исполняемого файла.
  4. /Tdc: это флаг командной строки, указывающий линковщику использовать определенный формат исполняемого файла.
  5. MyProg.obj: это имя объектного файла, который будет использоваться в процессе линковки.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 3.667 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут