1

So actually my question already has answer like below but it doesn't work for some case.

So I'm making immediate arithmetic floating point SSE instruction. We know SSE instruction like addsd doesn't support immediate so I make a bit higher abstraction with few instructions of SSE:

.macro add_float_immediate xmm, imm
  .pushsection .data
    .ifnotdef "const_\imm"
      "const_\imm": .double \imm #it will not create duplicate label.
    .endif
    movsd xmm0, \xmm
    movsd xmm1, "const_\imm"
    addsd xmm0, xmm1
  .popsection
.endm

So when the macro called several times with same immediate value, it will not create duplicate immediate value in memory so I can say it's memory saving. Like this example:

add_float_immediate xmm0, 3.14 #will create new label with name const_3.14
add_float_immediate xmm1, 3.14 #doesn't create new label, const_3.14 already exist.
add_float_immediate xmm2, 3.14 #doesn't create new label, const_3.14 already exist.
add_float_immediate xmm2, 2.71 #will create new label with name const_2.71

This is work only the case where operand 2 is number, doesn't work for immediate string with escape character.

Like this:

_print: # creating print function so macro will not copy syscall many times
  mov rax, 1 #kernel convention syswrite
  mov rdi, 1 #kernel convention stdout
  syscall #call kernel
  ret

.macro print_imm imm
  .ifnotdef "const_\imm"
    .pushsection .data
      "const_\imm": .ascii "\imm"
      "const_len_\imm"= . - "const_\imm"
    .popsection
  .endif

  //implementing syscall:
  lea rsi, "const_\imm"
  mov rdx, "const_len_\imm"
  call _print
.endm

This is what happened when I called macro:

print_imm "Hello " #will print "Hello " working fine.
print_imm "World\n" #Error: invalid character '\' in operand 2

I suspect error in lea and mov operand when defining macro print_imm. It's okay if fix my error is impossible but if there are another alternative about my problem how do I print immediate with unique label with GNU assembler?

Citra Dewi
  • 213
  • 3
  • 12
  • 1
    If you put your constants in a special section, you might be able to get the linker to merge duplicates. (GNU `ld` supports that, and GCC uses it for deduplicating string literals). That would even work across files, unlike assemble-time macros. – Peter Cordes Jul 19 '22 at 01:59
  • BTW, your x86-64 example forgot to use a RIP-relative LEA. If you're not going to use `lea [rip + "const_\imm"]`, it's pointless and inefficient to use LEA at all, and you should use `mov esi, OFFSET "const_\imm"`. [How to load address of function or label into register](https://stackoverflow.com/q/57212012) And of course these read-only constants should be in `.rodata` for efficiency, not `.data` along with mutable data (private mapping, pages will often get dirtied). Or `.rdata` on Windows, and I forget what name on MacOS. – Peter Cordes Jul 19 '22 at 02:01
  • Can you give me example about GNU ```ld``` that will deduplicating constant? – Citra Dewi Jul 19 '22 at 02:15
  • So I should use ```esi``` instead of ```rsi``` ? I thought assembler optimizer like ```-Os``` already do it for me. – Citra Dewi Jul 19 '22 at 02:35

0 Answers0