Подтвердить что ты не робот

Почему вы не можете установить указатель инструкции напрямую?

Статья в Википедии о сборке x86 гласит, что "к IP-адресу нельзя напрямую обращаться программистом".

Прямо означает с помощью команд, таких как mov и add.

Почему бы и нет? В чем причина этого? Каковы технические ограничения?

4b9b3361

Ответ 1

Вы не можете получить к нему доступ напрямую, потому что нет законного варианта использования. Любое произвольное изменение команды eip очень затруднит предсказание ветвления и, вероятно, откроет целый ряд проблем безопасности.

Вы можете редактировать eip с помощью jmp, call или ret. Вы просто не можете напрямую читать или писать на eip с помощью обычных операций

Установка eip в регистр так же просто, как jmp eax. Вы также можете сделать push eax; ret, который подталкивает значение eax в стек, а затем возвращает (т.е. Всплывает и переходит). Третий вариант - call eax, который выполняет вызов адреса в eax.

Чтение может быть выполнено следующим образом:

call get_eip
  get_eip:
pop eax ; eax now contains the address of this instruction

Ответ 2

Это был бы возможный дизайн для x86. ARM делает выставлять свой счетчик программ для чтения/записи как R15. Однако это необычно.

Он позволяет очень компактную функцию пролог/эпилог, наряду с возможностью нажатия или всплытия нескольких регистров с помощью одной команды: push {r5, lr} при записи и pop {r5, pc} для возврата. (Отображение сохраненного значения регистра ссылок в счетчик программ).

Тем не менее, он делает реализацию ARM с высоким приоритетом/невыполнением заказов менее удобным и был сброшен для AArch64.


Так что возможно, но использует один из регистров. 32-разрядная ARM имеет 16 целых регистров (включая ПК), поэтому номер регистра занимает 4 бита для кодирования в машинном коде ARM. Другой регистр почти всегда связан как указатель стека, поэтому ARM имеет 14 универсальных регистров общего назначения. (LR может быть сохранен в стеке, поэтому он может быть и используется как регистр общего назначения внутри тел функции).

Большинство современных x86 унаследовано от 8086. Оно было спроектировано с довольно компактной кодировкой команд переменной длины и всего 8 регистров, для которых требуется всего 3 бита для каждого регистра src и dst в машинный код.

В исходном 8086 они не были очень универсальными, а относительная адресация по SP не возможна в 16-битном режиме, поэтому по существу 2 регистра (SP и BP) привязаны к файлу стека. Это оставляет только 6 регистров общего назначения, и одним из них является ПК вместо общего назначения, это будет огромным сокращением доступных регистров, что значительно увеличит количество разливов/перезагрузки в типичном коде.


AMD64 добавлен r8-r15 и режим относительной адресации RIP. lea rsi, [rip+whatever] и RIP-относительные режимы адресации для прямого доступа к статическим данным и константам - все, что вам нужно для эффективного независимого от позиции кода. Непрямые инструкции JMP вполне достаточны для записи в RIP.

На самом деле ничего не может быть сделано, если разрешить использование произвольных инструкций для чтения или записи ПК, так как вы всегда можете сделать то же самое с регистром целого числа и косвенным прыжком. Было бы почти чистым недостатком для x86-64 R15, чтобы быть тем же самым, что и RIP, особенно для архитектуры performace в качестве цели компилятора. (Рукописный материал ASM был уже очень необычной нишей к 2000 году, когда был разработан AMD64.)

Итак, AMD64 - это первый случай, когда x86 мог бы получить полностью открытый программный счетчик, такой как ARM, но было много серьезных причин не делать этого.

Ответ 3

jmp установит регистр EIP.

этот код установит eip на 00401000:

mov eax, 00401000
jmp eax ;set Eip to 00401000

и для получения EIP

call GetEIP
.
.
GetEIP:
mov eax, [esp]
ret

Ответ 4

Я думаю, что они имели в виду, что доступ к IP-адресу невозможен напрямую так же, как к другим регистрам. Программисты могут определенно писать на IP, например, выдавая инструкцию перехода.