1

i'm trying to learn some assembly. All i want to do is declare an external c function with an input and an output string as parameters, and modify it with assembly. From what i know, arrays are always passed by reference. Here is a c example:

extern int mod_array(char input[], char output[]);
char input[SIZE]={'0','1','1','0','1'};
char output[SIZE]={'x','x','x','x','x'};
mod_array(input, output);

So i was thinking that fetching the address and modify the memory space will work. Here is a piece of assembly

   .data
    label: .string "s"
.text
    .global mod_array

mod_array:
    pushl %ebp #setup
    movl %esp, %ebp #setup

    movl 12(%ebp), %edx #fetching the address of the output array
    movl  label, (%edx) #moving label to the pointed space (first char of array)
    #error  


    popl %ebp #setup
    ret

The assembler produce an error. "Too many reference for mov". Now i can't understand if the problem is the variable label that i used, maybe because it does not have the dimension of 1B or if this is a sintax problem. Am i using an addressing mode that doesn't exists?

Is correct to think that, if i'm able to modify the space of memory pointed in asssembly, then also c main will see the changes?

Thanks

  • How are you trying to connect between the languages? – Roy Avidan Jul 09 '18 at 11:34
  • What is `SIZE`? Are you sure that the `output` array (I assume you mean to use) is as the position you think? And why do you want to copy a *pointer* into the first element of the array? – Some programmer dude Jul 09 '18 at 11:35
  • 1
    As the error says, you can't have two memory references in a `mov`. Use a temporary register, e.g. `mov label, %al; mov %al, (%edx)`. – Jester Jul 09 '18 at 11:40
  • i'm not trying to copy a pointer in the first element of the array. I'm tryng to put a random char with assembly into the first element of array. SIZE is simply the dimension of the array, i don't think this is important. From what i understand when i use: mod_array(input, output) i'm putting on top of the stack the two pointers and i can fetch them using movl 8(%ebp), register for the first and 12(%ebp) for the second since address takes 4B. I know that in the example input string is completely useless, i've only declare that because after i fix this problem i was thinking to try other things – GianMariaFilippo Verdi Jul 09 '18 at 11:40
  • `label` is really a pointer to the string `"s"`. You try to move (copy) that pointer into where `%edx` is pointing. And `%edx` is (if your code is correct) pointing to the first element (a single `char`) of the `output` array. If you want to copy the string pointed to by `label`, then you need a loop. Unless you only want to copy a single character from the string. – Some programmer dude Jul 09 '18 at 11:43
  • So here is where i'm wrong, label is a pointer. Is there a way to fetch the value of label? – GianMariaFilippo Verdi Jul 09 '18 at 11:45
  • You mean the value *at* a label? Jester already answered that: use an 8-bit temporary register. The value *of* a label is its address, which you'd get as an immediate with `mov $label, dst` – Peter Cordes Jul 09 '18 at 11:48
  • IDK why you want to store `'s'` in memory as data, instead of as an immediate, though. `movb $'s', (%edx)` would work. You could pull the constant away from the instruction that uses it with `equ` or `=`, though. See [Is there a symbol that represents the current address in GNU GAS assembly?](https://stackoverflow.com/q/8987767) for examples. – Peter Cordes Jul 09 '18 at 11:54
  • I don't think this is a dupilcate of the other question as marked - as that was using two indexes where it shouldn't. One thing GianMariaFlippo Verdi, you want to move a byte, please use movb or use the example given by Jesper. Plus can you run this all through a debugger - that will show you exactly what is going on! (Best way to learn) – Neil Jul 09 '18 at 12:43

0 Answers0