【问题标题】:(x86-64) GNU Assembly macro(x86-64) GNU 汇编宏
【发布时间】:2022-10-15 23:10:50
【问题描述】:

我刚开始学习汇编,但对 .macro 函数感到困惑。我已经能够找到用于在一个范围内添加一些数字但没有与字符串相加的示例。如果我想编写一个宏来重复 3 行文本,代码会是什么样子?

#编辑

我和我的导师谈过,他提供了一个我用来编写下面的汇编代码的例子:

.altmacro

.macro .printPlusPlus a
.print "\a"
.endm


.printPlusPlus <Hello, programmers!!>
.printPlusPlus <Welcome to the world of,>
.printPlusPlus <Linux assembly programing!!>

【问题讨论】:

  • 你是什​​么意思重复3行文字?你能举个例子吗
  • 这是一个作业,我必须打印“你好,程序员!欢迎来到 Linux 汇编编程的世界!”使用 gnu 宏

标签: assembly macros x86-64 gnu-assembler


【解决方案1】:

GAS 有一个.rept 宏,可以让你重复一些代码n次。此外,.macro 页面中的第一个示例基本上为您提供了另一种创建 .repeat times,another_macro 宏的方法,该宏可以将其称为第二个参数 times 次。

我基本上从来没有真正使用过 GAS,下面的代码只是一个 PoC。

它显示了如何使用.rept、上面提到的.repeat 宏以及sys_writesys_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

【讨论】:

  • 我尝试运行您的代码,但我得到“stack.c:汇编程序消息:stack.c:83:错误:没有这样的指令:share' stack.c:84: Error: no such instruction: edit'”
  • as thecode.S -o thecode.o 在我的机器上工作。你似乎是内联的,因为我的代码中没有 stackshare