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

Зачем использовать "movl $1,% eax" в отличие от, скажем, "movb $1,% eax",

Как говорится в заголовке, зачем использовать "movl $1,% eax" в отличие от, скажем, "movb $1,% eax", мне сказали, что movl будет обнулять старшие биты% eax, но не является ли% eax регистром, который эквивалентен размеру словесной системы? что movl на самом деле является целочисленной операцией (а не длинной?)

Я явно немного смущен обо всем этом; Спасибо.

4b9b3361

Ответ 1

против, скажем, "movb $1,% eax"

Эта инструкция недействительна. Вы не можете использовать eax с инструкцией movb. Вместо этого вы использовали бы 8-битный регистр. Например:

movb $1, $al

но не является% eax регистром, который эквивалентный размеру системы wordsize?

Нет. EAX всегда будет 32-битным значением, независимо от размера системного регистра.

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

Сборка проще, чем C. В сборке GAS в инструкциях добавляются буквы "b", "s", "w", "l", "q" или "t", чтобы определить, какой размер операнда манипулируют,

* b = byte (8 bit)
* s = short (16 bit integer) or single (32-bit floating point)
* w = word (16 bit)
* l = long (32 bit integer or 64-bit floating point)
* q = quad (64 bit)
* t = ten bytes (80-bit floating point)

Эти размеры постоянны. Они никогда не будут изменены. al всегда 8 бит, а eax всегда 32 бит.

Ответ 2

На 32-битной машине% eax является 4-байтным (32-разрядным) регистром. movl будет записывать во все 4 байта. В вашем примере он будет обнулять верхние 3 байта и поместить 1 в младший байт. Movb просто изменит младший байт.

Ответ 3

%eax - это 32-разрядный регистр. Чтобы использовать меньшую ширину, вам нужно %ax для 16 бит. %ax можно далее разделить на %ah для старшего байта %ax и %al для младшего байта. То же самое относится к другим GPR-серверам x86.

Глядя на инструкцию набора инструкций Intel для инструкции mov, я не вижу вариант, который может переместить один байт в 32-битный регистр - он, вероятно, интерпретируется как переход в %al.

Так как movl - это 32-разрядная команда, значения для верхних байтов будут соответствовать нулям в случае немедленного значения. Если бы вы переходили из памяти, вы перемещали бы все 32-битное слово.

%eax не обнуляется, если вы не movl $0, %eax, или если вы xorl %eax, %eax. В противном случае он сохраняет любое значение ранее. Когда вы movl $1, %eax, вы получите 0x00000001 в регистре, потому что 32-разрядная команда перемещает 32-битное мгновенное значение в регистр.

Ответ 4

long изначально было 32 бит, тогда как int и short равнялись 16. И имена кодов операций не меняются каждый раз, когда кто-то выходит с новой операционной системой.

Ответ 5

Ваш второй выбор просто приведет к ошибке, x86 не имеет этой инструкции. X86 является немного уникальным по отношению к загрузке байтов в определенные регистры. Да, на большинстве архитектур набора инструкций операнд равен нулю или расширенным значком, но x86 позволяет писать только младший байт или младшие 16 бит некоторых из них.

Есть, конечно, другие варианты, такие как очистка регистра и затем его увеличение, но вот три изначально разумно выглядящих вариантов:

   0:   b8 01 00 00 00          movl   $0x1,%eax

   5:   31 c0                   xorl   %eax,%eax
   7:   b0 01                   movb   $0x1,%al

   9:   b0 01                   movb   $0x1,%al
   b:   0f b6 c0                movzbl %al,%eax

Первый из них - 5 байт, второй - 4, третий. Таким образом, второй - лучший выбор, если оптимизировать пространство, иначе я полагаю, что наиболее вероятным будет быстрый запуск. В наши дни X86 является глубоко конвейерной, поэтому две команды будут блокироваться, и машине может потребоваться довольно много состояний ожидания в зависимости от деталей аппаратного обеспечения конвейера.

Конечно, эти операционные системы x86 переводится в зависимости от процессора в микрооперации процессора, и так кто знает, что произойдет.

Ответ 6

%eax - 32 бит на 32-разрядных машинах. %ax - 16 бит, а %ah и %al - его 8-битные высокие и низкие составляющие.

Поэтому movl здесь совершенно справедливо. Эффективность, movl будет такой же быстрой, как movb, и обнуление высоких 3 байтов %eax часто является желательным свойством. Возможно, вы захотите использовать его как 32-битное значение позже, поэтому movb не является хорошим способом перемещения байта.