Ошибка использования dword ptr
В языке ассемблера, если мы используем
mov eax, dword ptr[ebx]
то это означает, что нужно скопировать значение, указанное ebx (ebx содержит значение адреса, а не фактическое значение, эта команда копирует фактическое значение в адресе)?
Если мы используем
mov eax, dword ptr[some_variable]
то это означает, что копировать значение переменной "some_variable" непосредственно в eax, а не копировать значение, указанное переменной "some_variable"?
Правильно ли я понимаю?
Если да, я смущен, почему одна и та же инструкция сборки имеет два разных значения - в первом случае существует уровень косвенности, но во втором нет дополнительного уровня косвенности.
Любые комментарии?
EDIT:
Не каждый [] не имеет никакого эффекта, например, команда xchg будет принимать уровень в направлении, который загружает значение, указанное edx.
Целый исходный код можно найти из
http://www.codeproject.com/KB/threads/spinlocks.aspx
#ifdef WIN32
inline int CPP_SpinLock::TestAndSet(int* targetAddress, int nValue)
{
__asm {
mov edx, dword ptr [pTargetAddress]
mov eax, nValue
lock xchg eax, dword ptr [edx]
}
}
#endif // WIN32
Ответы
Ответ 1
В обоих случаях вы попросите процессор переместить значение с указанного адреса. Это один уровень косвенности. В первом случае вы просите его взять адрес из указанного регистра. Во втором случае вы прямо указываете смещение.
Процессоры x86 не поддерживают двунаправленную косвенность, поэтому невозможно запросить загрузить значение из адреса, указанного где-то в памяти, - вы должны загрузить адрес в регистр.
Под несколькими сборщиками (например, MASM и встроенными в ассемблер VС++) вы можете написать просто
mov eax, dword ptr some_variable
без скобок, это будет означать то же самое.
Вы можете написать
move eax, dword ptr [variable][ebx]
это даст указание принять адрес "переменной", затем добавить значение ebx и использовать сумму в качестве адреса, из которого нужно загрузить значение. Это часто используется для доступа к элементам массива по индексу.
Во всех этих случаях процессор будет делать то же самое - загрузить значение с указанного адреса. Это один уровень косвенности каждый раз.