LINUX.ORG.RU

GNU Assembler перегрузка макросов


0

0

Хотел написать макрос позволяющий вызывать функции, вот так:

invoke FunctionName, param1, param2, ...

Но сталкнулся с проблемой - у каждой функции разное количество параметров, а значит вызовы выглядят по разному. Перегрузить макрос по количеству параметров не получилось. Пробовал использовать .ifdef чтобы определять передан параметр или нет - не вышло. Остановился на таком варианте - после invoke писать количество параметров. В результате написал несколько макросов для разного количества параметров:

.macro invoke1 function, par1 push \par1 call \function add $4, %esp .endm

.macro invoke2 function, par1, par2 sub $8, %esp movl \par2, 4(%esp) movl \par1, (%esp) call \function add $8, %esp .endm

и т.д. В принципе короче чем каждый раз полностью писать вызов, но чиселки после invoke не очень красиво смотряться. Есть идеи как такое провернуть без написания отдельного макроса для каждого числа параметров?

Ответ на: комментарий от mv

А можно попродробнее, а то гугль чё-то ничего интересного по теме не находит... Как потом обращатся к параметрам внутри макроса? Как обращатся к их количеству?

LinuxUser ★★★
() автор топика
Ответ на: комментарий от LinuxUser

Найти и почитать документацию на gas (он в binutils входит)? Я не уверен, что к ним можно будет обращаться внутри самого invoke.

mv ★★★★★
()
Ответ на: комментарий от mv

Он в GCC входит. Документацию я нашёл вот тут http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-assembler/mac... но там про vararg ничего нету. Собственно если внутри invoke к ним нельзя обращатся то vararg не катит, потому как в обращении к параметра внутри invoke весь смысл.

LinuxUser ★★★
() автор топика
Ответ на: комментарий от mv

Спасибо, это документация полнее. Но там не написано как обращатся к параметрам по отдельности, судя повсему это невозможно.

Кстати Opera почему-то сругнулась на этот сайт: "Fraud Warning. The page you are trying to open has been reported as fraudulent. It will likely attempt to trick you into sharing personal or financial information." Кто-то пошутил что-ли...

LinuxUser ★★★
() автор топика
Ответ на: комментарий от LinuxUser

Можно попробовать сделать кучу параметров с каким-нибудь умолчательным значением, которые разгребать в теле макроса с помощью .if

mv ★★★★★
()
Ответ на: комментарий от mv

Ага, была такая идея и с .if и с .ifdef но не получилось.

Почитал http://sourceware.org/binutils/docs/as/If.html и нашёл такую штуку .ifnb - проверяет есть ли вообще чё. Вообщем набросал такой код:

.macro invoke function:req, par1, par2, par3, par4 .ifnb \par4 sub $16, %esp movl \par4, 12(%esp) movl \par3, 8(%esp) movl \par2, 4(%esp) movl \par1, (%esp) .else; .ifnb \par3 sub $12, %esp movl \par3, 8(%esp) movl \par2, 4(%esp) movl \par1, (%esp) .else; .ifnb \par2 sub $8, %esp movl \par2, 4(%esp) movl \par1, (%esp) .else; .ifnb \par1 push \par1 .endif; .endif; .endif; .endif call \function .endm

Стек не чищу потому что вызывал WINAPI функции (проверял на MinGW-шном as). Работает! :) mv спасибо большое.

LinuxUser ★★★
() автор топика
Ответ на: комментарий от LinuxUser

.macro invoke function:req, par1, par2, par3, par4
.ifnb \par4
	sub $16, %esp
	movl \par4, 12(%esp)
	movl \par3, 8(%esp)
	movl \par2, 4(%esp)
	movl \par1, (%esp)
.else; .ifnb \par3
	sub $12, %esp
	movl \par3, 8(%esp)
	movl \par2, 4(%esp)
	movl \par1, (%esp)
.else; .ifnb \par2
	sub $8, %esp
	movl \par2, 4(%esp)
	movl \par1, (%esp)
.else; .ifnb \par1
	push \par1
.endif; .endif; .endif; .endif
	call \function
.endm

LinuxUser ★★★
() автор топика
Ответ на: комментарий от mv

В регистрах ты имеешь ввиду прям в функцию?. Насколько знаю в регистрах только своим функциям можно передавать, или я чего не знаю? :)

LinuxUser ★★★
() автор топика
Ответ на: комментарий от LinuxUser

Вместо записи в стек записывать в регистры (в определённом порядке). Можно сделать так же, как gcc делает.

mv ★★★★★
()
Ответ на: комментарий от LinuxUser

Удобнее mri-синтаксис в этой ситуации (-M):

$ as -alm -M macro.s -o macro.o
GAS LISTING macro.s                     page 1
 
 
   1                            .macro  abc,func,a,b,c,d,e,f,g,h
   2                            .if NARG > 2
   3                            .set i,1
   4                            .irp test, a b c d e f g h
   5                            movl    test, i*4-4(%esp)
   6                            .set i,i+1
   7                            .endr
   8                            .else
   9                            .if NARG > 1
  10                            push    a
  11                            .endif
  12                            .endif
  13                            call func
  14                            .endm
  15
  16                            abc     add,$3,$2,$1
  16                    > .if 4>2
  16                    > .set i,1
  16                    > .irp test,$3 $2 $1
  16 0000 C7442400      >> movl $3,i*4-4(%esp)
  16      03000000
  16                    >> .set i,i+1
  16                    >>
  16 0008 C7442404      >> movl $2,i*4-4(%esp)
  16      02000000
  16                    >> .set i,i+1
  16                    >>
  16 0010 C7442408      >> movl $1,i*4-4(%esp)
  16      01000000
  16                    >> .set i,i+1
  16                    > .else
  16                    > .if 4>1
  16                    > push $3
  16                    > .endif
  16                    > .endif
  16 0018 E8FCFFFF      > call add
  16      FF
  17                            abc     sub,$6
  17                    > .if 2>2
  17                    > .set i,1
  17                    > .irp test,$6
  17                    > movl test,i*4-4(%esp)
  17                    > .set i,i+1
  17                    > .endr
  17                    > .else
  17                    > .if 2>1
  17 001d 6A06          > push $6
  17                    > .endif
  17                    > .endif
  17 001f E8FCFFFF      > call sub
  17      FF
  18                            abc     sin
  18                    > .if 1>2
  18                    > .set i,1
  18                    > .irp test,
  18                    > movl test,i*4-4(%esp)
  18                    > .set i,i+1
GAS LISTING macro.s                    page 2
 
 
  18                    > .endr
  18                    > .else
  18                    > .if 1>1
  18                    > push
  18                    > .endif
  18                    > .endif
  18 0024 E8FCFFFF      > call sin
  18      FF
  19

io ★★
()
Ответ на: комментарий от io

sub забыл вставить:

   1                            .macro  abc,func,a,b,c,d,e,f,g,h
   2                            .if NARG > 2
   3                            sub $ (NARG-1)*4,%esp
   4                            .set i,1
....

io ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.