Да, указатели - это просто целые числа, конечно, вы можете вычесть их, например. с sub si, di
.
Предполагая, что они смещены относительно одной и той же базы сегмента (например, модель крошечной / маленькой или плоской памяти), результат на самом деле имеет смысл: расстояние в байтах между указанными ячейками памяти.
Один случай использования - это то, что упомянул @fuz: получение индекса массива из указателя. например Вы можете реализовать strlen
, увеличив указатель, затем в конце выполните sub ax, si
, чтобы получить длину.
Конечно, для меток, определенных в текущем файле, расстояние является постоянной времени сборки, поэтому вам нужно просто попросить ассемблер рассчитать ее для вас. Я думаю mov si, OFFSET v5 - v2
- правильный синтаксис MASM. В NASM это будет просто mov si, v5 - v2
. И с этими определениями вы получите si=2
независимо от того, делаете ли вы это во время сборки с v5 - v2
или с инструкцией sub
времени выполнения, потому что dw 4
имеет ширину 2 байта.
Или функция, которая принимает 2 входа массива как 2 указателя + длину, может проверять наложение, вычитая и принимая абсолютное значение, чтобы увидеть, меньше ли оно длины. См. Должны ли сравнения указателей быть подписаны или не подписаны в 64-битной x86?
Это точно так же, как вычитание указателей в C, за исключением того, что вы управляете компоновкой статических данных, поэтому нет никаких ограничений относительно того, что имеет смысл делать, или любого неопределенного поведения. (За исключением C, вычитание указателя масштабируется по ширине шрифта. Так что на самом деле это похоже на приведение к uintptr_t
перед вычитанием.)