Вопреки распространенному мнению, директива org
не говорит ассемблеру , куда поместить код. Он сообщает ассемблеру, что считать указателем инструкции (IP) в этой точке. Во многих инструкциях x86 используются относительные адреса, поэтому ассемблеру необходимо знать смещение кода в сегменте.
Когда DOS загружает файл .COM, он устанавливает префикс сегмента программы в 0000 и загружает ваш код в 0100, который также является адресом, по которому он инициализирует IP.
Чтобы проиллюстрировать вопрос об орг:
если вы сделаете это
org 100H
call 123H
вы получите звонок по адресу 123H, как вы ожидаете:
0CD3:0100 E82000 CALL 0123 ; call IP + 20H (IP = 100H + 3)
Но если вы сделаете это
org 105h
call 123h
тогда, когда вы посмотрите на разборку, вы увидите, что вам не позвонили по номеру 0123H, несмотря на call 123H
прямо перед вашими глазами в тексте сборки. Вместо этого вы получите
0CD3:0100 E81B00 CALL 011E ; call IP + 1BH
Причина несоответствия заключается в том, что когда вы писали org 105H
, вы, по сути, лгали ассемблеру - вы говорили, что предполагаете, что код был на 105H, тогда как на самом деле DOS будет загружать код на 100H независимо. Поэтому во втором примере смещение в инструкции вызова отключено на 5 байт.