2016-04-18 12 views
2

Я прочитал книгу Кипа Ирвина Assembly Language for x86 Processors и он писал:Ведущий Zero в расширении знака в сборке x86?

Копирование меньших значений к большим

Хотя MOV не может напрямую копировать данные из меньшего операнда большего размера, программисты могут создавать обходные пути. Предположим, что count (unsigned, 16 bits) необходимо перенести в ECX (32 бит). Мы можем установить ECX к нулю и переместить счетчик в CX:

.data 
count WORD 1 
.code 
mov ecx,0 
mov cx,count 

Что произойдет, если мы пытаемся тем же подход, с знаковым целым числом, равным -16?

.data 
signedVal SWORD -16 ; FFF0h (-16) 
.code 
mov ecx,0 
mov cx,signedVal ; ECX = 0000FFF0h (+65,520) 

Значение в ECX (+65,520) полностью отличается от -16. С другой стороны, если бы мы имели заполненный ECX первой с FFFFFFFFh, а затем копируются signedVal в CX, значение NAL фи было бы правильно:

mov ecx,0FFFFFFFFh 
mov cx,signedVal ; ECX = FFFFFFF0h (-16) 

Моей проблема с последней частью. Я думаю, что первая строка в коде выше должна была написать mov ecx,FFFFFFFFFh, а не 0FFFFFFFFh. Другими словами, что является ведущим нолем?

+0

'mov ecx, -1' должен работать. –

ответ

4

Для того, чтобы сказать этикетки и числовых литералов обособленно большинство сборщиков требуют последних из них в всегда начинаются с цифрой, даже если это только не существенный нуль.

Если вы считаете число значащим шестнадцатеричными цифрами в 0ffffffffh, вы видите, что они действительно восемь, каждый из которых несет четыре бита информации.
И 8 раз 4 равно 32.
Ваш буквальный fffffffffh вместо этого - 36 бит.

Проще говоря, как номера daha7h, e0h и так далее, должны быть написаны с ведущим 0.
В вашем уме вы должны автоматически избавиться от лишних нулей.

+0

спасибо, что я пропустил этот пункт – user3661613

0

Чтобы различать символы (например, переменные) и номера, вы должны начинать цифры с десятичной цифры.

Числовой параметр для mov ecx всегда хранится как 32-разрядный независимо от числа, если цифры записываются в коде (если конечное значение меньше 2^32). Ведущие нули игнорируются.

В отличие от номеров C/C++, начинающихся с 0, не интерпретируются как восьмеричные числа (если это вас беспокоит). Октальные числа начинаются с 0t.