Компилятор сгенерирует соответствующие инструкции для подписанных и неподписанных случаев. Я думаю, что может быть лучше увидеть пример. Следующий код
void foobar();
void foo(unsigned char a)
{
if (a < 10)
foobar();
}
void bar(char a)
{
if (a < 10)
foobar();
}
переведет в этот код MIPS с G CC 5.4, используя флаг -O3
.
foo:
andi $4,$4,0x00ff
sltu $4,$4,10
bne $4,$0,$L4
nop
j $31
nop
$L4:
j foobar
nop
bar:
sll $4,$4,24
sra $4,$4,24
slt $4,$4,10
bne $4,$0,$L7
nop
j $31
nop
$L7:
j foobar
nop
Это интересная часть функции foo
(которая использует тип unsigned char
)
foo:
andi $4,$4,0x00ff
sltu $4,$4,10
Как вы можете видеть, используется команда sltu
, которая является невидимой версия slt
. (Вам не обязательно знать, что он делает)
Хотя, если мы посмотрим на функцию bar
релевантная часть
bar:
sll $4,$4,24
sra $4,$4,24
slt $4,$4,10
Вы увидите, что используется slt
, который будет обрабатывать его операнд регистра как подписанный. Пара sll
и sra
делает расширение знака, так как здесь операнды a
были подписаны, так что это необходимо, в то время как в случае без знака это не так.
Таким образом, вы могли видеть, что различные инструкции генерируются относительно знак операндов.