Ошибка при перемещении постоянного байтового значения в% ebx

Я работаю над Computer Systems, A Programmer's Perspective (3-е издание), а практическая задача 3.3 содержит следующую строку:

movb $0xF, (%ebx)

Я должен выяснить, что не так с этой линией сборки x86-64, а ключ ответа гласит: «Невозможно использовать% ebx в качестве регистра адреса», что для меня не имеет смысла. Насколько я понимаю, эта строка намерена скопировать 0xF в место в основной памяти, однако% ebx - это 32-битный регистр, адреса памяти имеют ширину 64 бита на 64-битных машинах, и поэтому% ebx не может содержать адрес памяти, поэтому его нельзя разыменовать (разыменование - это то, что обозначают круглые скобки вокруг% ebx, правильно?). Однако, если заглянуть на несколько страниц назад в книгу (стр. 183, если она у вас есть), можно увидеть пример, детализирующий пять комбинаций операнда mov - назначения, одна из которых:

movb $-17, (%esp)         Immediate--Memory, 1 byte

% esp - это 32-битный регистр, как и% ebx! В этом примере показано, как значение байта перемещается в разыменованный 32-битный регистр! Что для меня не имеет смысла, потому что как% esp может содержать 64-битный адрес? Я совсем неправильно понял сборку?


person Peter Delevoryas    schedule 26.07.2015    source источник
comment
Вы можете использовать 32-битный адрес и в 64-битном режиме, если вы знаете, что ваш адрес находится в 32-битном диапазоне. Обычно стека нет, поэтому (%esp) опасен.   -  person Jester    schedule 26.07.2015
comment
Говорил ли предыдущий пример о 32-битном коде x86? Вы правы, что размер 32-битного адреса неуместен в 64-битном коде, если только вы не разместили свои адреса в низком 4 ГиБ виртуальной памяти (например, Linux x32 ABI). В обычных системах Linux сегменты текста, данных и bss отображаются в младшие 32 бита виртуального адресного пространства, а стек - нет. Stackoverflow, безусловно, получает вопросы, ответ на которые состоит в том, что вы собрали 32-битный пример в 64-битную программу, поэтому вы потерпели неудачу, усек адрес.   -  person Peter Cordes    schedule 26.07.2015
comment
Спасибо Jester и Peter Cordes, я не знал, что вы можете обращаться, используя 32-битный режим в 64-битном режиме. Кроме того, нет, я не верю, что в этом примере говорится о 32-битном коде x86, потому что 3-я глава была полностью переписана для 3-го издания, чтобы представить сборку x86-64. Может быть, я напишу авторам по электронной почте, чтобы они добавили исправления в книгу. Спасибо!!!   -  person Peter Delevoryas    schedule 26.07.2015


Ответы (2)


Вы правы,

movb $-17, (%esp)         Immediate--Memory, 1 byte

нельзя допускать. Фактически авторы разместили это как опечатку. Ознакомьтесь с их списком исправлений (Ctrl-F для "стр. 183") .

person FahimApple    schedule 11.10.2017
comment
Он кодируется, но обычно дает сбой, если только старшие 32 бита %rsp не равны нулю. Это тот случай, если ваш стек находится в низком 4G памяти. Linux x32 ABI использует 32-битные указатели в 64-битном режиме (для экономии места в кэше в код, насыщенный указателями, и избегайте префиксов REX при работе с указателями), так что это будет действительным там. В любом случае, я думаю, вы хотели сказать, что это плохой пример. Спасибо за обновление, что это была ошибка в книге. - person Peter Cordes; 11.10.2017

Для 64-битной x86; в инструкции movb $0x0F, (%ebx) нет ничего плохого. Он собирается в 0x67, 0xC6, 0x03, 0x0F.

Книга неправильная.

Обратите внимание, что все инструкции могут быть ошибками (простой пример: использование add, когда вы хотели использовать sub), а movb $0x0F, (%ebx) может быть ошибкой (например, возможно, значение должно было быть 0xFF, возможно, предполагалось использовать другой регистр, может быть, это предполагалось использовать rbx, может быть lea, ..). Это не означает, что это всегда ошибка (например, 32-битные адреса совершенно законны, а иногда желательны в 64-битном коде).

person Brendan    schedule 08.02.2019
comment
Инструкция выполняется без генерации исключения о недопустимой инструкции. Более точное объяснение можно найти здесь: stackoverflow.com/a/30291334/683727 - person wuxb; 03.01.2020