gudleifr писал(а):
(CALL, в 16- и 32- разрядном коде, может быть трех видов: байтовый (short) - относительный, словный (near) - относительно начала сегмента, двусловный (far) - тоже абсолютный. Обычно все используют near, а сегменты выставляют на все 4Гб 32-разрядной памяти, что делает его абсолютным).
Впрочем, если я вам мешаю, то лучше пишите в личку, когда возникнет потребность, а здесь пусть вещают наши манагеры.
Я думаю, манагеры могли бы навещать, что представленные варианты адресации существуют никак не для CALL, а для JMP. А для call наиболее распространены rel16/rel32, а байтовых вызовов подпрограмм вообще не существует. Абсолютный call действительно имеется, но т.н. near автоматически использует разрядность смещения, совпадающую с режимом работы процессора, поэтому в 32-разрядном режиме это как раз и будет 32 бита. Абсолютные форматы вызова используются в основном в привилегированном режиме работы для передачи управления между задачами или в системные функции (т.е. все равно, по сути, в другую задачу). В этом случае первая часть (т.е., к примеру, 16:32) - это вовсе не старшая часть, а номер селектора. Так сложно сделано потому, что в защищенном режиме уже не напастись полей, поэтому области памяти задач описываются сложной структурой-дескриптором. Дескрипторы имеют фиксированный размер, и вот их номер в специальной таблице и хранится в регистрах CS/DS/ES/SS/FS/GS. В данном случае неактуально на 99%, поэтому можно просто писать 0xE8 xx yy zz ww (четыре байта смещения, 0 == не переходить никуда).
И да, call near отсчитывает смещение не относительно начала сегмента, а относительно следующей команды. Есть варианты call indirect, например, call eax, тогда в eax надо загрузить сам адрес перехода.
Например:
http://x86.renejeschke.de/html/file_module_x86_id_26.htmlТо, что коды команд совпадают, относится как раз к разнице между 16 и 32-битными режимами. С давних времен про 16-битный можно забыть. При особой необходимости можно использовать специальный префикс замены адреса (однобайтный код 0x67), который в 32-битном режиме заставит использовать 16-битное смещение (и наоборот), но на практике это имеет очень слабую актуальность.