Rambler's
Top100

Основы архитектуры x86

Автор: lonesome TSH/Digital Daemons
Дата: .01.2003
Раздел: Низкоуровневое программирование в Linux

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

Регистры

Регистры - особые ячейки памяти, находящиеся прямо в процессоре. Скорость доступа к ним очень велика, поэтому их желательно использовать для хранения данных, обращения к которым очень часты (например для счетчика цикла). В отличие от ячеек оперативной памяти, которые имеют фиксированную длину в 1 байт, регистры могут быть разной длины. Регистры, которые вы можете использовать практически всегда - это четырехбайтные регистры EAX, EBX, ECX, EDX, EDI, ESI, причем младшие два байта этих регистров можно адресовать под именами AX, BX, CX, DX, DI, SI соотвественно, а первые четыре из этих "половинчатых" регистров разделяются на AH и AL, BH и BL, CH и CL, DH и DL, соответственно
Еще два регистра общего назначения - EBP и ESP используются для операций со стеком, поэтому их можно использовать только в том случае, если вы точно знаете. что их содержимое не понадобится.

Специальный регистр EIP является указателем адреса текущей инструкции, т.е. процессор всегда выполняет инструкцию находящуюся по этому адресу. Команды передачи управления в другую точку программы на самом деле изменяют значение регистра EIP.

Регистр флагов EFLAGS содержит 32 бита, которые используются как флаги. Если значение какого-либо бита равно 1, то считается, что соотвествующий флаг установлен. Некоторые команды процессора изменяют значения флагов этого регистра. На этом механизме основана система условных переходов. Наиболее часто используемые флаги:
CF(Carry Flag - флаг переноса),
PF(Parity Flag - флаг четности),
AF(Auxiliary Carry Flag - дополнительный флаг переноса),
ZF(Zero Flag - флаг нуля),
SF(Sign Flag - флаг знака),
DF(Direction Flag - флаг направления),
OF(Overflow Flag - флаг переполнения),

Сегментные регистры CS, DS, ES, SS, FS, GS используются для хранения селекторов сегментов. При программировании под Linux они нам не понадобятся, поскольку Linux предоставляет непрерывное адресное пространство в 4 гигабайта памяти. Про сегментную адресацию можно прочитать здесь

Кроме этих регистров существуют другие, но они не используются в пользовательских программах и применяются в основном ядром ОС для контроля памяти, прерываний и пр.

Адресация

Адресация - способ задания операнда. Наиболее простые способы адресации - регистровая (операнд - регистр) и непосредственная адресация (операнд - константа) уже были рассмотрены в предыдущем уроке.. Кроме них существуют следующие способы адресации операндов, находящихся в оперативной памяти:
mov al, [0x1234] - поместит в регистр AL байт, находящийся по адресу 0x1234. Здесь 0x1234 - константа, т.е. если где либо в программе определена метка label, то взять один байт по адресу label можно точно так же:
mov al, [label]

Задавать адрес в оперативной памяти можно не только с помощью констант, но и с помощью регистров:
mov al, [ecx+0x1234] - адрес равен константе плюс содержимое регистра ECX

Так можно использовать до двух регистров, причем значение одного из них может масштабироваться - умножаться на 2, 4 или 8. Самая сложная возможная адресация памяти выглядит вот так:
[const+reg1+reg2*m], где const - константа, reg1 и reg2 - регистры, а m - масштаб (множитель)
Например:
mov al, [0x1234+eax+ecx*4]



Rambler's Top100