Tendo uma formação matemática pura, essa é uma abordagem um pouco mais matemática para qualquer pessoa interessada.
Se começarmos com um número inteiro assinado e sem sinal de 8 bits, o que temos é basicamente o número 256 do módulo inteiro, no que diz respeito à adição e multiplicação, desde que o complemento 2 seja usado para representar números inteiros negativos (e é assim que todo processador moderno faz isso) .
Onde as coisas diferem está em dois lugares: um são operações de comparação. Em certo sentido, o número inteiro do módulo 256 é melhor considerado um círculo de números (como o número inteiro do módulo 12 em um relógio analógico à moda antiga). Para fazer comparações numéricas (é x <y), precisamos decidir quais números são menores que os outros. Do ponto de vista do matemático, queremos incorporar os números inteiros módulo 256 no conjunto de todos os números de alguma forma. Mapear o número inteiro de 8 bits cuja representação binária é todos os zeros para o número 0 é a coisa mais óbvia a se fazer. Podemos então mapear outros para que '0 + 1' (o resultado de zerar um registro, digamos ax, e incrementá-lo por um, via 'inc ax') vá para o número inteiro 1, e assim por diante. Podemos fazer o mesmo com -1, por exemplo, mapeando '0-1' para o número inteiro -1 e '0-1-1' para o número inteiro -2. Devemos garantir que essa incorporação seja uma função, portanto, não é possível mapear um único número inteiro de 8 bits para dois números inteiros. Como tal, isso significa que, se mapearmos todos os números no conjunto de números inteiros, 0 estará lá, juntamente com alguns números inteiros menores que 0 e outros mais que 0. Existem essencialmente 255 maneiras de fazer isso com um inteiro de 8 bits (de acordo com para o mínimo desejado, de 0 a -255). Então você pode definir 'x <y' em termos de '0 <y - x'.
Existem dois casos de uso comuns, para os quais o suporte a hardware é sensato: um com todos os números inteiros diferentes de zero sendo maior que 0 e outro com uma divisão de aproximadamente 50/50 em torno de 0. Todas as outras possibilidades são facilmente emuladas pela conversão de números por meio de um acréscimo adicional. e sub 'antes das operações, e a necessidade disso é tão rara que não consigo pensar em um exemplo explícito no software moderno (já que você pode trabalhar com uma mantissa maior, digamos 16 bits).
A outra questão é a de mapear um número inteiro de 8 bits no espaço de números inteiros de 16 bits. -1 vai para -1? É isso que você deseja se 0xFF representar -1. Nesse caso, a extensão de sinal é a coisa mais sensata a ser feita, de modo que 0xFF vá para 0xFFFF. Por outro lado, se 0xFF deveria representar 255, você deseja que ele seja mapeado para 255, daí para 0x00FF, em vez de 0xFFFF.
Essa é a diferença entre as operações de 'turno' e 'turno aritmético' também.
Por fim, no entanto, tudo se resume ao fato de que int's em software não são números inteiros, mas representações em binário, e apenas alguns podem ser representados. Ao projetar o hardware, é necessário fazer escolhas sobre o que fazer nativamente no hardware. Como no complemento 2, as operações de adição e multiplicação são idênticas, faz sentido representar números inteiros negativos dessa maneira. Então é apenas uma questão de operações que dependem de quais números inteiros suas representações binárias devem representar.