16-битный регистр может адресовать только до 0xFFFF (65 536 байт, 64 КБ).Когда этого было недостаточно, Intel добавила сегментные регистры.
Любой логический проект просто объединял бы два 16-разрядных регистра для создания 32-разрядного адресного пространства (например, 0xFFFF : 0xFFFF = 0xFFFFFFFF
), но nooooo ... Intel пришлось запутаться в нас.
Исторически передняя шина (FSB) имела только 20 адресных линий и, следовательно, могла передавать только 20-битные адреса.Чтобы «исправить» это, Intel разработала схему, в которой сегментные регистры расширяют ваш адрес только на 4 бита (16 бит + 4 = 20, в теории).
Для достижения этой целиСегментный регистр смещен влево от своего первоначального значения на 4 бита, а затем добавлен к адресу в общем регистре (например, [es:ax] = ( es << 4 ) + ax
) . Примечание. Сдвиг влево на 4 бита эквивалентен умножению на 16 .
Вот и все.Вот несколько иллюстративных примеров:
;; everything's hexadecimal
[ 0:1 ] = 1
[ F:1 ] = F1
[ F:0 ] = F0
[ F:FF] = 1EF ; [F becomes F0, + FF = 1EF]
[ F000 : FFFF ] = FFFFF (max 20-bit number)
[ FFFF : FFFF ] = 10FFEF (oh shit, 21-bit number!)
Итак, вы все равно можете адресовать более 20 бит.Что просходит?Адрес «оборачивается», как модульная арифметика (как естественное следствие аппаратного обеспечения).Итак, 0x10FFEF
становится 0xFFEF
.
И вот оно у вас!Intel наняла немых инженеров, и мы должны с этим жить.