Вызов на mc:
сохранит текущий адрес, поэтому, когда вернется subr:
, управление снова начнется с mr:
.
, так как subr:
толкает топор, бх и скс вэтот порядок.Затем он добавляет топор, bx и cx в этом порядке, поэтому то, что было вытолкнуто из cx, попадает в топор (и наоборот).В результате они меняются топором и cx.add ax, dx
не оказывает реального влияния на полученный результат, потому что сразу после добавления dx к топору он выталкивает топор из стека.add
действительно влияет на флаги, но здесь ничто не делает ничего, основанного на флагах, поэтому, по крайней мере, в показанном вами коде это тоже мало что значит.
После того, как управление вернется к mr:
, он записывает значение в ax
в память, а затем возвращается обратно в subr:
, таким образом меняя топор и cx обратно туда, откуда они начались.
IOW, в целом это очень медленное, обходное движениеспособ достижения примерно того же эффекта, что и:
mc: mov [val], cx
ret
Что касается абсолютного адреса, сказать особо нечего.В частности, весьма вероятно, что если вы снова запустите тот же код, он может быть загружен по другому адресу, или адрес, сохраненный в стеке, может быть совершенно другим.