Перейти к содержанию
FHell

Не могу до конца освоить прямую/косвенную адресацию.

Рекомендуемые сообщения

Здравствуйте. Начну с примера

fstp dword ptr [edi]
// По адресу [edi] лежит, скажем, current_float
// Рядышком, в [edi+4] лежит maximum_float
// Задача записать maximum_float вместо current_float
// Как я вижу решение:
fstp dword ptr [edi]
mov [edi], [edi+4]
// Конечно, это не работает и моя проблема заключается в том, что я не понимаю почему данная запись не верна.
// Workaround1:
fstp dword ptr [edi]
push eax
  mov eax, [edi+4]
  mov [edi], eax
pop eax
// Workaroud2:
fstp dword ptr [edi]
fld dword ptr [edi+4]
fstp dword ptr [edi]

Собственно вопрос, какое решение является лучшим и почему запись вида "mov [edi], [edi+4]" не верна.

Изменено пользователем FHell
Опечатка в названии темы

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
2 часа назад, FHell сказал:

моя проблема заключается в том, что я не понимаю почему данная запись не верна

Как насчет решить проблему, почитав документацию к интересующей тебя инструкции ассемблера?

 

2 часа назад, FHell сказал:

какое решение является лучшим

То, которое ты почему-то назвал Workaround 2, хотя по факту оно и есть правильное исходя из вышеупомянутой документации.

 

И да, кстати, что конкретно ты подразумеваешь под прямой и косвенной адресацией?

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата

И да, кстати, что конкретно ты подразумеваешь под прямой и косвенной адресацией?

Если левый операнд edi - это прямая регистровая адресация, то [edi] - это косвенно-регистровая адресация.

Цитата

Как насчет решить проблему, почитав документацию к интересующей тебя инструкции ассемблера?

Rtfm это, безусловно, хороший совет. И я читал про команды ассемблера. Но я просто не понимаю некоторые описанные в ней моменты :)

Вот например вырезка с av-assembler:

Спойлер

При использовании этой команды следует учитывать, что имеются некоторые ограничения. А именно, инструкция MOV не может:

  • Записывать данные в регистры CS и IP.
  • Копировать данные из одного сегментного регистра в другой сегментный регистр (сначала нужно скопировать данные в регистр общего назначения).
  • Копировать непосредственное значение в сегментный регистр (сначала нужно скопировать данные в регистр общего назначения).

ИСТОЧНИКОМ может быть один из следующих:

  • Область памяти (MEM)
  • Регистр общего назначения (REG)
  • Непосредственное значение (например, число) (IMM)
  • Сегментный регистр (SREG)

ПРИЁМНИКОМ может быть один из следующих:

  • Область памяти (MEM)
  • Регистр общего назначения (REG)
  • Сегментный регистр (SREG)

С учётом ограничений, которые были описаны выше, комбинации ПРИЁМНИК-ИСТОЧНИК могут быть следующими:


REG,  MEM
SREG, MEM
MEM,  REG
REG,  REG
SREG, REG
MEM,  IMM
REG,  IMM
MEM,  SREG
REG,  SREG

Пример использования инструкции MOV:


MOV AX, 0B800h    ; установить AX = B800h (память VGA).
MOV DS, AX        ; копировать значение из AX в DS.
MOV CL, 'A'       ; CL = 41h (ASCII-код).
MOV CH, 01001110b ; CH = атрибуты цвета (желтый текст на красном фоне).
MOV BX, 72eh      ; BX = позиция на экране = 2*(x + y*80).
MOV [BX], CX      ; [0B800h:015Eh] = CX.

По всей видимости, я упускаю какой-то важный момент. Если я думаю, что операция mov [edi], [edi+4] должна работать. Буду признателен, если вы меня "тыкните носом".

P.S. если и [edi], и [edi+4] это области памяти MEM, то почему я не могу сделать mov MEM, MEM.

 

Изменено пользователем FHell
дополнил

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
8 часов назад, FHell сказал:

Собственно вопрос, какое решение является лучшим и почему запись вида "mov [edi], [edi+4]" не верна.

Из памяти в память напрямую писать нельзя.
нужно либо юзать регистр, утебя это:

Спойлер

push eax
  mov eax, [edi+4]
  mov [edi], eax
pop eax

 


либо стек у тебя это:

Спойлер

fld dword ptr [edi+4]
fstp dword ptr [edi]

 


Я лично предпочитаю юзать mov


 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
4 часа назад, FHell сказал:

почему я не могу сделать mov MEM, MEM

Потому, что архитектура процессора этого не позволяет. Ограничения, о которых написано в твоей выжимке - это ограничения архитектуры процессора. 

Представь, что у тебя есть два аквариума, отделенных друг от друга стенкой. И еще чуть подальше у тебя есть третий аквариум. Первый и второй аквариум соединены с третьим трубкой, но никак не соединены между собой. 

Дальше представь, что тебе надо немного воды из первого аквариума загнать во второй. Напомню - первый и второй аквариумы архитектурно между собой не связаны. И ты можешь из первого налить в третий, а потом

из третьего - во второй. Можешь из второго налить в третий, и из него - в первый. А потом стоишь и спрашиваешь, а почему ты не можешь налить сразу из первого во второй. И вот тебе ответ - нет между ними трубки, не предусмотрено. 

Это и есть архитектурное ограничение. Предвосхищая твой вопрос "почему до сих пор не сделали" - потому что, процессор при работе всегда копирует данные из оперативки в свою внутреннюю память - регистры и кеш, потому что сколь бы ни была память оперативная быстрой, все равно работа с ней будет медленее, чем с собственным кешем процессора. Ограничения системной шины и законов физики. Потому, если интересно, рекомендую прокопать глубже эту тему, благо, материалов в интернетах полным-полно. И да, сравнение я привел, разумеется, довольно грубое, но хорошо иллюстрирующее ответ на твоё "почему".

 

Если лень было читать всё, что выше, скажу кратко - твой вопрос выглядит как "у моего велосипеда есть два колеса, я могу на нем катиться вперед, могу катиться назад. А почему я не могу катиться вбок?"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за ответы, пояснения и предоставленные аналогии)  Всё понял, закрепил, усвоил.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Предпросмотр

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.