Прежде всего, ни один из режимов адресации в оригинале не использует индексный регистр. [ebx+8]
может (и будет) использовать EBX в качестве базового регистра, а не индексный регистр, поскольку он может сделать это без байта SIB в кодировке машинного кода. Таким образом, режим адресации база + disp8, так что кодирование ModRM байт будет (в двоичной системе)
- Mod = 01 (основание + disp8)
- R/M = 011 (EBX)
- REG = 000 (EAX в качестве места назначения регистра)
Таким образом, байт ModRM будет 0x43, согласно Таблица 2-2. 32-битные формы адресации с байтом ModR/M, в справочном руководстве по набору инструкций Intel (том 2). (См. Wiki x86 для ссылок на файлы PDF).
Если на EBX был коэффициент масштабирования (например, [ebx*2 + 8]
), ему пришлось бы использовать режим адресной адресации disp32 +. (См. Также x86 addressing modes).
Предположительно, вы фактически имеете в виду, что вы не можете использовать перемещение в режиме адресации.
В этом случае первой инструкцией не может быть нагрузка, поскольку вам необходимо сначала вычислить адрес в регистре. Вопрос облегчает вам, позже вычисляя то же самое значение ebx+8
, которое вам нужно в качестве адреса, используя инструкцию ADD. Таким образом, вы можете просто изменить порядок, вместо того, чтобы дважды изменять EBX.
add ebx, 8
mov eax, [ebx]
add eax, 1
mov [ebx], eax
или медленнее, но меньше инструкции:
add ebx, 8
add dword [ebx], 1 ; read-modify-write
mov eax, [ebx] ; and then reload
x86 имеет много странных и прекрасных инструкций, в том числе XADD. Можно даже сделать это:
; LEA ebx, [ebx+8] might count as breaking the rules, even though it's not a load.
sub ebx, -8 ; use a different instruction just for variety.
mov eax, 1
xadd dword [ebx], eax ; read-modify-write, leaving the old value in eax
inc eax ; do the same add again, so the register matches what xadd put into memory.
Но не делайте этого. XADD медленнее, чем обычные простые инструкции. Основной целью является многопоточная синхронизация. C++ 11's std::atomic::fetch_add - это та же самая операция, которую реализует XADD, поэтому fetch_add() может эффективно скомпилировать x86 до lock xadd
.
Это совершенно неправильно. Вы читаете неправильное местоположение в своем первом решении, а также читаете и записываете неправильные местоположения во втором месте. –
О, это больно, хорошо спасибо за быстрый комментарий! Позвольте мне попытаться исправить это. –
, если ebx = 1000, тогда 'mov eax, [ebx + 8]' загружает eax с 32b значением из адреса 1008. Ваш 'mov eax, [ebx]' будет загружать eax с 32b значением из адреса 1000. Если я понимаю, что правильность формулировки задачи, то это в каком-то смысле меньше, чем в первой попытке. – Ped7g