Почему тогда ассемблерные программы не портируемы?
Потому что программа, написанная на Ассемблере для IBM/360 никогда не заработает на IBM PC :) несмотря на то, что изначально как бы делались одной конторой :)
В 1990 - 1995 годах я очень много программировал на IBM/360, на PL/1 и ассемблере (а там другого не было), гигантские программы писал, сотни макросов имел в запасе.
После того, как перешел на i8086 - большая часть этих знаний пошла в корзину, осталось только общее понимание того, как устроен процессор :)
Ассемблер - это самый нижний из доступных уровней разработки, на нем сейчас пишут только misson-critical секции, потому что это реально машинно-зависимо - на другом семействе процессоров даже той же самой архитектуры уже может не заработать, на другой архитектуре не заработает гарантированно.