Во-первых, вы ошиблись. В беззнаковом типе 1111.1111 = 255 (а не 256!), в знаковом типе 1111.1111 = −1 (а не −127).
1000.0000 — соответственно −128 и 128.
256 не передашь одним байтом — ни в знаковом типе, ни в беззнаковом.
Ну и ответ на ваш главный вопрос.
> Как ЭВМ понимает, какое число положительное, а какое отрицательное?
Если заведомо известно, что в ячейке знаковое число — как сказано выше, по верхнему биту (1 — минус, 0 — ноль или плюс). А различить знаковое и беззнаковое число — работа, вообще-то, не машины, а программиста и компилятора, и если просто дана ячейка неизвестного типа — никак не узнаешь, signed там, unsigned, дробное, указатель или символ.
• Сложение и вычитание работает одинаково для знаковых и беззнаковых чисел.
• Проверка переполнений и сравнение. Используются три флага: флаг равенства (zf, zero), флаг знакового переполнения (of, overflow) и флаг беззнакового переполнения (cf, carry). Каждая из арифметических функций заполняет и знаковые, и беззнаковые флаги, и есть отдельные функции ветвления для беззнаковых чисел (above/below — например, ja, jbe = jna…) и для знаковых (greater/less — jg, jle = jng). Jump if above, jump if below or equal, и т.д.
• Умножение и деление — также разные функции, беззнаковая mul/div и знаковая imul/idiv.
Кстати, по этой причине компилятор ругается, если нужно сравнивать signed и unsigned. Единственный способ надёжно сделать это, например, для 4-байтовых чисел — расширить до 8-байтового signed, чтобы уместился и тот, и другой.