I don't know how to reference it, if I use macro, and the parameter seems to a string, and if I use addressing mode on it, then macro get the string yet, like (test), $test
, .etc.
Below code just for example!!
.macro newcat str
newcat:
.string "\str"
.equ newcat_len, .-newcat
.endm
.section .data
test:
.string "abc"
# expect newcat has string "abc", but it got string "test"
newcat test
.section .text
.globl _start
_start:
movq $1, %rax
movq $1, %rdi
movq $newcat, %rsi
movq $newcat_len, %rdx
syscall
movq $60, %rax
syscall
CodePudding user response:
You can't read memory contents at assemble time, with or without macros. You can't assemble bytes into some section and then have another directive copy those bytes somewhere else.
What you can do is define a new symbol to have the same address as another symbol, which is obviously more efficient for read-only data (.section .rodata
). You'd only want to actually duplicate the ASCII bytes as initializers for mutable .data
, or in some rare case if you needed unique addresses for two things even though the data happened to be the same. (Perhaps as LUT entries for a struct { int i; char s[4];} table[16];
or something.)
.section .rodata
str1:
str2: # you can have 2 labels that happen to have the same address
.asciz "Hello"
# at any point later
.set str3, str1 # an alias, just like if you'd put str3: before/after str2:
Hopefully this example also makes it clearer that labels only happen to be followed by data, they aren't like C variables where it's the one and only way to reference that location.
If you want the same string data twice without having it appear again literally in your file, the string itself needs to be a macro. And you need to reference that macro name, not some label that happens to be followed by some pseudo-instructions that emit some data there.
.macro foo
.asciz "the text"
.endm
.data
str1: foo
str2: foo
If you want, you could have the macro take a symbol name as a parameter and include those labels, and even define a .equ
with another name derived from that if you want.
Or with the C preprocessor (name the file foo.S
and build with gcc -c
instead of plain as
). I'm not sure if GAS's own macro language allows macros like this that expand to a single token, not a whole line. I find it cumbersome compared to NASM.
#define foo "the text"
.data
str1: .asciz foo
str2: .asciz foo
Other assemblers work the same way, for example NASM: Assemble-time read the value of a data variable