2

I'm in the process of porting NASM code to MASM, and I'm stuck on a NASM empty macro with 2 parameters and register usage with the _m suffix.

example code:

;register defines %define arg0 rcx %define arg4 r12 %define tmp4 r14 %define len arg0 %define dest1 arg4 %define dest2 tmp4 %define PS 8 ;empty macro %macro SLDR 2 %endmacro %define SSTR SLDR ; example usage in code: SLDR len, len_m sub len, 16 SSTR len_m, len jl .return0 ;... SLDR dest1, dest1_m mov dest2, [dest1+PS] SSTR dest2_m, dest2 mov dest1, [dest1] SSTR dest1_m, dest1 

I assume the _m parameters are macro generated names, but what register(s) do they represent (assuming they are not on the stack)?

5
  • After adding a .return0: label anywhere in your MCVE, we can assemble it and see what registers the normal instructions use. To see what if anything dest2_m expands to, you could make the macro non-empty, like using %warn, or xor %1, %2 or something and look at the error messages. In this case, macros.asm:20: error: symbol 'len_m' not defined (godbolt.org/z/P38E676dc). I didn't think there was any magic with _m names in NASM, and this confirms it. %1 = rcx and %2 = len_m in the first use of SLDR for example. Commented Aug 6, 2025 at 10:02
  • (With the macro still empty, you can assemble + disassemble to check what machine register got used.) Commented Aug 6, 2025 at 10:02
  • @PeterCordes The NASM preprocessor directive is %warning, not %warn Commented Aug 6, 2025 at 10:37
  • 1
    @PeterCordes - in Nassau's comment to the answer below he notes that the 32 bit versions defined len_m and arg0_m, along with usage of the SLDR and SSTR macros. Support for X86 32 bit was removed from Intel ISA-L erasure code . They should have either deleted the lines using SLDR and SSTR or commented them out with an explanation. I've ported one of the asm files gf_vect_dot_prod_sse.asm to Visual Studio | MASM and it's working. Some of the register renames are poor: x0 for xmm0 but xtmpa for xmm1? Commented Aug 6, 2025 at 16:38
  • @PeterCordes - I 've since imported the entire Intel ISA-L repository using Visual Studio 2022 | 2026 using NASM to build the libraries as is, as well as taking a small sub-set of the erasure code and my own MASM code for testing purposes. The Intel library doesn't have any code that uses GFNI (vgf2p8affineqb) with XMM registers so I created a set of source files just to test it. Based on web search, Intel P5362 is an example of a processor that supports GFNI, but not AVX..., so GFNI with XMM only. Commented Mar 19 at 2:02

2 Answers 2

5

In this case:

  • parameter_m is just a literal argument passed into the macro.

  • The macro doesn’t know or care what register parameter_m is unless you define it elsewhere.

If parameter_m is not defined, then NASM throws an error like:
error: symbol `parameter_m' undefined. (Or it would if your macro used this token as an operand to an instruction, rather than in a %define or stringifying it or something. As is, it assembles cleanly since the empty macro does nothing with it.)

Sign up to request clarification or add additional context in comments.

4 Comments

I need to investigate this, but I think you are correct, the empty macro does nothing, so there's no error reported for using an undefined name like len_m. My guess is that at some point or in some cases, the SLDR and SSTR were doing something, and that len_m was defined in those cases, but no longer used. In some of the other files, there are defines for XLDR and XSTR and those do something (normally used to load a zmm register from memory or store a zmm register into memory.
Looking at the code, it appears that SLDR and SSTR were changed to nops (empty macro), the define for len_m was removed, but the lines of code using SLDR and SSTR were left in. I don't understand why those lines were not deleted or commented out with some explantion.
If I understood this correctly, if output file is 64-bit (elf/win), macro SLDR is empty, no complains from NASM. For 32-bit version there are other %define statements available: %define len_m arg0_m-> %define arg0_m arg(0) -> %define arg(x) [ebp + PS*2 + PS*x] -> %define PS 4 so len_m = [ebp + 8] and SLDR 2 code is mov %1, %2. Here is link, opendev.org/openstack/deb-libisal/src/branch/master/…
That would explain it. Support for X86 32 bit was removed from Intel ISA-L erasure code . They should have either deleted the lines using SLDR and SSTR or commented them out with an explanation. I've ported one of the asm files gf_vect_dot_prod_sse.asm to Visual Studio | MASM and it's working. Some of the register renames are poor: x0 for xmm0 but xtmpa for xmm1?
0

len_m, dest1_m, etc. do not represent any register. In NASM, they are just macro arguments/symbols, not predefined names. In your snippet, SLDR and SSTR are empty macros, so those parameters are effectively ignored. The _m suffix is a naming convention, typically meaning a “mirror” or “memory” version of a variable (e.g., a stack slot or alternate storage). In other builds, these macros might expand to instructions like mov %2, %1, where *_m would be defined elsewhere. In your current code, however, they have no effect and no register mapping.

1 Comment

As I commented to the accepted answer, SLDR and SSTR were used for the 32 bit versions, and 32 bit versions were removed from the library. What I don't get is why the lines of code with SLDR and SSTR weren't removed as opposed to leaving references to empty macros. I removed those lines in both MASM and NASM test code without issue.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.