Макросы NASM с «многострочными аргументами»

Вероятно, это не лучший заголовок для вопроса, но я хочу просто передать несколько строк сборки в макрос nasm. Или, что то же самое, я хочу, чтобы макрос реализовал шаблонные «верх» и «низ» некоторого блока кода, но с произвольной серединой.

В качестве конкретного примера рассмотрим следующий источник nasm:

%assign regn 8
%rep 8
%define reg r %+ regn
lea reg, [rsp - 8]       ; body
push reg                 ; body
%assign regn (regn + 1)
%endrep

Это перебирает все регистры от r8 до r15 и генерирует две строки «основного» кода для каждой, с результатом вроде:

lea    r8,[rsp-0x8]
push   r8
lea    r9,[rsp-0x8]
push   r9
lea    r10,[rsp-0x8]
push   r10
lea    r11,[rsp-0x8]
push   r11
lea    r12,[rsp-0x8]
push   r12
lea    r13,[rsp-0x8]
push   r13
lea    r14,[rsp-0x8]
push   r14
lea    r15,[rsp-0x8]
push   r15

Я хотел бы извлечь этот шаблон "цикл по 8 регистрам", который представляет собой все строки, не отмеченные выше как ; body, в какой-то макрос, чтобы я мог вызывать его с разными типами тел.

Если бы тело было только одной строкой, это было бы так же просто, как:

%macro loop_r8_r15 1
%assign regn 8
%rep 8
%define reg r %+ regn
%1       ; body
%assign regn (regn + 1)
%endrep

Однако я не могу найти естественный способ расширить это на несколько строк. Думаю, я мог бы использовать макрос, который принимает один или несколько аргументов, а затем «перебирает» их в теле, но это означает, что вам нужно записать вызов макроса в одной строке со вставкой каждой строки, а не естественным однострочным -за инструкцию, как вы хотели бы это написать. Я также не уверен, как это работает, если само тело содержит вызовы макросов или другие директивы.

Я не знаю, возможно ли это с макроязыком NASM. Я предполагаю, что пример, который вы приготовили, не был настоящим кодом, но если бы это было так, вы могли бы сделать это более эффективно на Intel (без операций синхронизации стека) с lea r9, [r8 - 0x8] / lea r10, [r8 - 0x10] и так далее.

Peter Cordes 18.09.2018 22:41

@PeterCordes, на самом деле это являетсянастоящий код для проверки задержек при поиске указателей. Я уверен, что это могло бы быть более эффективным: например, вы могли бы легко векторизовать всю часть push с помощью широковещательной передачи, и пара добавлений, а затем записать все это двумя 32-байтовыми записями - но это код настройки за пределами критической области, поэтому «правила простоты».

BeeOnRope 19.09.2018 01:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
705
0

Другие вопросы по теме