2

Let's say that I have a struc in NASM defined like this:

struc tcb_t
  .a resb 1
  .b resb 1
endstruc

I want to have an array of instances of the above type. Let's say that I have at most 64 threads running and each of them should store some information in such a struct. Each thread knows it's id, so in C we would do it similarly to this:

tcb_t tcbs[64] = {0};
[...]
tcbs[task_id].a += 1

But what's the syntax like for NASM? I wasn't able to find it in their documentation, i.e.:

  • how to define an array of strucs?
  • how to find the size of a struc?
  • knowing the size of a struct, we can't do much better than mov rax, [tcbs + rcx * sizeof_tcb_t], can we?
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • `rcx * sizeof_tcb_t` only works if it's 1, 2, 4, or 8. (Or if there's no other register, NASM will allow 3, 5, or 9 by splitting it into `[tcbs + rcx + rcx*2]` for example.) This is assembly language; That C statement needs to compile to multiple asm instructions unless you have `task_id` in a register already, and the struct size is something an x86 addressing mode can do. NASM struct support will never make one source line assemble into multiple machine instructions, but I think you can use it for offsets within a struct. (I never bothered with it, so I'd have to google how.) – Peter Cordes Apr 25 '22 at 11:07
  • `add byte [tcbs + rcx * sizeof_tcb_t + tcb_t.a], 1` looks like the right syntax to use the offset of a within `tct_t` as a constant. [NASM - How to make array of struct pointers and access them](https://stackoverflow.com/q/26412158). As for sizeof, you might want to do that with `.size equ $ - .a` after the struct declaration or something like that to define `tct_t.size`, same as you would to get the assembler to calculate the size for normal non-struct data, as in [How does $ work in NASM, exactly?](https://stackoverflow.com/q/47494744) – Peter Cordes Apr 25 '22 at 11:11
  • [Error "non-constant argument supplied to TIMES" from istruc use of a structure](https://stackoverflow.com/q/71471039) has an answer from ecm doing lots of complicated stuff with NASM struct support, including arrays of them I think. – Peter Cordes Apr 25 '22 at 11:15
  • Oh actually, the manual (https://www.nasm.us/doc/nasmdoc5.html#section-5.9) does point out that NASM defines `tcb_t_size` for you automatically, just from using the `struc` macro like you're doing. [Is NASM 'times' directive taken into account when calculating sizes?](https://stackoverflow.com/q/18721847) – Peter Cordes Apr 25 '22 at 11:31
  • oh, it does indeed! I have totally overlooked the `_size` thing. thank you! – Paweł Balawender Apr 25 '22 at 11:32
  • 1
    @PeterCordes I don't think my answer over there has arrays of structures but yes, there is the `_size` label defined for structures. It is instructive to remember how the `struc` macros just create labels in an `absolute` section (starting at zero, or with my patch accepted by NASM you can specify a nonzero start offset as the `%2` of `struc`). You can look at how they're implemented in the source: https://github.com/netwide-assembler/nasm/blob/3f9fc2a3a7134936cbbae5780beb4319694f702a/macros/standard.mac#L82-L109 – ecm Apr 25 '22 at 11:51
  • https://sourceforge.net/p/nasm/feature-requests/160/ Here's the feature request in which I added nonzero starting offsets for `struc`. – ecm Apr 25 '22 at 11:58
  • 1
    Anyway to define an array of structure `tcb_t` as a global variable you do `arraylabel: times tcb_t_size * 64 db 0` (in a writeable data section). – ecm Apr 25 '22 at 12:06
  • thanks! yes, that's exactly how i've done it - i tried to use ```%rep N istruc``` here, but it requires you to write down the struc's fields twice, which is totally unnecessary with uninitialized storage. it's best to forget about `istruc` and just use ```resb tcb_t_size * N``` – Paweł Balawender Apr 25 '22 at 12:09
  • @user3622836: You can use `%rep x` and just put `istruc tcb_t` then `iend`. The `at` macros are completely optional, you can use `istruc` with all, some, or none of the fields listed with `at`. – ecm Apr 25 '22 at 12:23

0 Answers0