Макрос

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

Модератор: Andy

Ответить
ррррррроман
Сообщения: 10
Зарегистрирован: 18 апр 2009, 15:59

13 май 2009, 18:15

Всем добрый вечер. Написал небольшую прогу, которая использует макрос. Макрос вычисляет значение выражения x=3((xxx+2y)(xxx+2y)-yyy-2y)-2(yyy+2x), имеет 2 формальных параметра.
При компиляции вылетает ошибка:
Ошибка: Illegal memory reference - Недопустимая ссылка на память. Это 74 строка в проге(в листинге я ее выделил красным цветом).
В чем я накосячил? :confused:
Да и еще вопрос, зачем в начале блока команд прописывать:

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

  
  mov ax, date; ???????????
  mov ds, ax; ???????????
Без этого прога отказывается корректно работать. (зачем опять вычислять начальный адрес сегмента команд, если я его вычислил выше
с помошью диррективы assume

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

assume ss:s, ds:date, cs:code
)

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

s segment stack
  db 256 dup(?)
s ends

date segment
  x dw 4
  y dw 6
  buf db 1,?,' '; буфер ввода
date ends

code segment
assume ss:s, ds:date, cs:code
  print proc near; процедура вывода числа на экран выводит содержимое регистра ax        
    push ax
    push cx
    push dx
    xor cx, cx; обнуление счетчика количества цифр в числе 
    cmp ax, 0; 
    jge pon0; если число >= 0
    push ax; если ax < 0, запись в стек
    mov ah, 2; функция 02 прерывания 21h
    mov dl, '-'
    int 21h; вывод минуса на экран
    pop ax; извлечение из стека
    ;neg ax; меняем знак на противоположный (в данном контексте не работает)
    mov cx, -1; вычисление модуля ax
    imul cx
    xor cx, cx; обнуление счетчика количества цифр в числе 
    pon0:
      xor dx, dx 
      div cs:ten; ax:= (dx, ax) div 10, dx:= (dx, ax) mod 10 
      push dx; запись в стек 
      inc cx
      or ax, ax 
      jnz pon0; наличие цифр в числе
    mov ah, 2; функция вывода символа прерывания 21h 
    pon1:
      pop dx; извлечение числа из стека  
      add dl, '0'; перевод цифры числа в символ 
      int 21h; вывод цифры на экран 
      loop pon1
    mov dl, ' '
    int 21h; вывод пробела после числа
    ;выход из процедуры
    pop dx
    pop cx
    pop ax    
    ret; передача управления
    ten dw 10; основание системы счисления  
  print endp
  expression macro x, y; определ. макроса x=3((xxx+2y)(xxx+2y)-yyy-2y)-2(yyy+2x)
    push ax
    mov ax, x
    irp ax, <ax, ax>; arp блок
      imul ax;; ax:= x*x*x
    endm
    add ax, y
    add ax, y; ax:= xxx + 2y
    .186
      imul ax,3; ax:= ax*ax*3
      imul x, x, -4; x:= -4*x
      add x, ax; x:= ax*ax*3 - 4*x
      imul ax, y, 6; ax:= 6*y          
      sub x, ax; x:= ax*ax*3 - 4*x - 6*y
      imul y, y, 1; y:= y*y
      imul y, y, 5; y;= y*y*y*5
      sub x, y; x:= ax*ax*3 - 4*x - 6*y - y*y*y*5  
    .186
    pop ax
  endm
begin:
  mov ax, date; ???????????
  mov ds, ax; ???????????   
  [color="Red"];expression x y[/color] 
  mov ax, x
  call print
  lea dx, buf; вычисление адреса буфера ввода
  mov ah, 0ah
  int 21h
  mov al, 0; возвращение кода завершения программы
  mov ah, 4ch
  int 21h
code ends
  end begin


--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
Свою ошибку нашел самостоятельно.
Она была здесь

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

.186
      imul ax,3; ax:= ax*ax*3
      imul ax, x, -4; ax:= -4*x
      add x, ax; x:= ax*ax*3 - 4*x
      imul ax, y, 6; ax:= 6*y          
      sub x, ax; x:= ax*ax*3 - 4*x - 6*y
      imul ax, y, 1; ax:= y*y
      imul ax, y, 5; ax:= y*y*y*5
      sub x, ax; x:= ax*ax*3 - 4*x - 6*y - y*y*y*5  
.186
первый операнд команды imul должен обязательно быть регистром, а я там прописал ячейку памяти. Исправил, все заработало.
Но второй непонятный мне момент остается нераскрытым. :rolleyes:
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

14 май 2009, 09:32

ррррррроман, ну сколько можно объяснять. Вот здесь все сказал уже -http://forum.developing.ru/showthread.php?t=17487
&quot писал(а):imul ax, y, 1; ax:= y*y
неверно, ax := y*1
&quot писал(а):ax:= y*y*y*5
поосторожнее с такими выражениями, при Y>23 выйдет за границы 16 бит
It's a long way to the top if you wanna rock'n'roll
Ответить