Как заголовок указывает, почему можно было бы использовать "movl 1$, %eax" в противоположность, скажем, "movb 1$, %eax", мне сказали, что movl обнулит высокого уровня биты %eax, но не является %eax регистр, это эквивалентно размеру wordsize системы? подразумевать, что movl находится в действительности целочисленная операция (и не длинное?)
Я ясно немного смущен всем этим; Спасибо.
в отличие, скажем, от "movb $ 1,% eax"
Эта инструкция является недействительным. Вы не можете использовать eax с инструкцией movb. Вместо этого вы должны использовать 8-битный регистр. Например:
movb $ 1, $ al
но не% eax регистр, который эквивалентный размеру системы словесный размер?
Нет. 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-битный.
На 32-битной машине% eax - это 4-байтовый (32-битный) регистр. movl запишет все 4 байта. В вашем примере он обнулит верхние 3 байта и поместит 1 в младший байт. Команда movb просто изменит младший байт.
% 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-битное непосредственное значение в регистр.
long
изначально было 32 бита, тогда как int
и short
были 16. И имена кодов операций не меняются каждый раз. кто-то выпускает новую операционную систему.
Второй вариант просто вызовет ошибку, 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, третий - 5. Таким образом, второй - лучший выбор при оптимизации по пространству, в противном случае я полагаю, что самый скорее всего, будет быстро бежать - это первый. В наши дни X86 имеет глубокую конвейерную обработку, поэтому две инструкции будут блокироваться, и машине может потребоваться довольно много состояний ожидания в зависимости от деталей оборудования конвейера.
Конечно, эти операции x86 транслируются специфичными для ЦП способами в микрооперации ЦП , и так что кто знает, что произойдет.
% eax
- 32 бита на 32-битных машинах. % ax
составляет 16 бит, а % ah
и % al
- это его 8-битные старшие и младшие составляющие.
Следовательно, movl
здесь совершенно справедливо. С точки зрения эффективности movl
будет таким же быстрым, как movb
, и обнуление старших 3 байтов % eax
часто является желательным свойством. Возможно, позже вы захотите использовать его как 32-битное значение, поэтому movb
не лучший способ переместить туда байт.