GAS 有一个.rept 宏,可以让你重复一些代码n次。此外,.macro 页面中的第一个示例基本上为您提供了另一种创建 .repeat times,another_macro 宏的方法,该宏可以将其称为第二个参数 times 次。
我基本上从来没有真正使用过 GAS,下面的代码只是一个 PoC。
它显示了如何使用.rept、上面提到的.repeat 宏以及sys_write 和sys_exit 的两个宏。
总而言之,我不喜欢它(我确信有更好的方法来编写宏)但它已被评论并且可以作为答案。
#
# Constants
#
SYS_WRITE=1
SYS_EXIT=60
STDOUT=1
#
#This macro is similar to .rept but it takes the body to repeat as an argument
#This argument should be a name denoting a macro with no arguments
#
.macro repeat times, body
#Call the macro
ody
#Recurse if the next value of times is not 0
.if imes-1
repeat "( imes-1)",ody
.endif
.endm
#
#This macro print the string text given as its argument
#This work by switching to the data section, defining a local label 0 before the string and
# a local label 1 after the string (so we can get the string length as the difference), switching
# back to the text section and inserting a system call for SYS_WRITE
#
.macro print text
#Write the string in the data section and sorround it with two labels
.section .data
0:
.string " ext"
1:
#Go back to the text section and invoke the system call
.section .text
mov $SYS_WRITE, %eax
mov $STDOUT, %edi
lea 0b(%rip), %rsi
mov $(1b-0b-1), %edx #The -1 is because GAS always add a null-term
syscall
.endm
#
#This is a simple macro to call SYS_EXIT returning the optional argument ret
#
.macro exit ret=0
mov $SYS_EXIT, %eax
mov $
et, %edi
syscall
.endm
#
#Since the repeat macro requires a 0-arity macro name, we need a wrapper macro for print
# with its string argument
#
.macro print_hello
print "Hello, programmers! Welcome to the world of, Linux assembly programming!
"
.endm
#
# CODE
#
.global _start
.section .text
_start:
#Use our repeat macro
repeat 3,print_hello
#Use GAS .rept
.rept 3
print "Hello scripters! This is not like assembly at all!
"
.endr
#Exit
exit