0

I have problem with understanding loops in asm. I'm trying to change value at index to '1' but i don't know how to increment %0 by x, currently x is 4 in code, but i dont know how to automatise this, to program to be able to read value of 'x' from register. I made some misconception then sorry but there is really not much in internet about GCC asm and i know i shouldn't do this but i just want to understand how this work

#include <stdio.h>

int main(void)
{
    const int size = 20;
    int index = 8;
    int arr[size]= {};
    __asm__(
        "movl   $1, %%eax;"
        //"add    $8, %%SP;"
        "movl   %%eax, 4%0;"
        : "+m"(*(arr))
        : "r"(size)
        : "memory"
        );
    for (int i = 0; i < 20; i++)
    {
        printf("%d \n", arr[i]);
    }
    return 0;
}
Botje
  • 26,269
  • 3
  • 31
  • 41
Hyacin
  • 9
  • 3
  • So you want to do `arr[index] = 1`? Note that does not need a loop. You are not even referencing `index` in your asm block so that can not work. You can do `"movl $1, %0" : "=m" (arr[index])`. – Jester Jun 08 '22 at 14:26
  • @Jester i trying to make insted of '4%0' to make offset of value what is in register that, this look like this: 0%0, 4%0, 8%0..... just to in later loop through this array. – Hyacin Jun 08 '22 at 14:58
  • So you maybe want `"movl $1, (%0, %1, 4)" :: "r" (arr), "r" (index) : "memory"` – Jester Jun 08 '22 at 15:05
  • @Jester got Error: `(%rax,%edx,4)' is not a valid base/index expression I just want to find out how to loop tru array, and change ever '0' to '1' but for this i dont know how to change this 4 in 4%0 to increment by 4 – Hyacin Jun 08 '22 at 15:22
  • You did not say you were in 64 bit mode ... well then use `(uint64_t)index`. Also to iterate an array you can just increment the pointer each time you don't need to scale an index. – Jester Jun 08 '22 at 15:25
  • 1
    @Jester sorry, forget to add -m32 now its working and i get how to do this. Thank you. – Hyacin Jun 08 '22 at 15:35
  • Your asm is unsafe: it's missing a clobber on `"eax"`. It also asks for `size` in the compiler's choice of register, but never accesses `%1`. And you should probably use something like `4+%0` or maybe `4+0%0`. If it expands to `16(%esp)`, you don't want `416(%esp)`, you want `4+16(%esp)`. – Peter Cordes Jun 08 '22 at 19:15
  • Also, you modify an array element other than the one you told GCC you were going to modify. `*arr` is just an `int`, specifically `arr[0]`, not the whole array like you'd get from asking for `"+m"(arr)`. (Decay to a pointer does *not* happen with asm constraints; you do get the whole array as a memory operand.) See [How can I indicate that the memory \*pointed\* to by an inline ASM argument may be used?](https://stackoverflow.com/q/56432259). But you use a `"memory"` clobber which should make that safe. If you used an accurate constraint, you wouldn't need that. – Peter Cordes Jun 08 '22 at 19:19
  • Re: actually looping: See [Looping over arrays with inline assembly](https://stackoverflow.com/q/34244185) for comparison of `"+m"` memory operand vs. asking for an address in a register if you're using an `asm` statement as the loop *body*, but writing the loop itself in C. – Peter Cordes Jun 08 '22 at 20:15

0 Answers0