Если макросы используют метки, то при вызове макроса мы можем столкнуться с проблемами:
.code equal macro op1, op2 cmp op1, op2 jz isEqual mov rax, 0 jmp exit isEqual: mov rax, 1 exit: endm main proc mov rcx, 2 mov rdx, 3 equal rcx, 2 equal rdx, 2 ret main endp end
Здесь макрос equal принимает два параметра и проверяет их на равенство. Если они равны осуществляется переход к метке isEqual, на которой в регистр RAX помещается число 1. Если числа не равны, в RAX помещается число 0, и происходит переход к метке exit.
Поскольку код макросов вставляется в место их вызова при компиляции, то мы получим ситуацию, что метки isEqual и exit будут определены два раза, что недопустимо, так как метка должна быть определена только один раз. Чтобы решить эту проблему, мы можем использовать локальные метки, которые задаются внутри макроса с помощью оператора local
local метка1, метка2, ... меткаN
Оператору local
передаются через запятую идентификаторы, которые используются внутри макроса. Так, изменим предыдущий пример, используя локальные метки:
.code equal macro op1, op2 local isEqual, exit ; объявляем локальные метки cmp op1, op2 jz isEqual mov rax, 0 jmp exit isEqual: mov rax, 1 exit: endm main proc mov rcx, 2 mov rdx, 3 equal rcx, 2 equal rdx, 2 ret main endp end