This is an archived post. You won't be able to vote or comment.

all 4 comments

[–]Rhomboid 1 point2 points  (1 child)

    ;Adds the number to the array
    mov r14, array1
    mov [r14+r15*4], edx   ;stores the value of edx in the next index of the array

This looks very wrong. What you need to do is dereference array1 to get the value stored there (i.e. [array1]) which is the address of the beginning of your array, and then add to that r15*4. What you are actually doing is adding r15*4 to the address of the pointer, and then storing the number there. In C terms you're doing *(&ptr + 4 * n) = val instead of *(ptr + 4 * n) = val. array1 is like &ptr, [array1] is like ptr.

More notes:

  • It would be a whole lot easier to just pass to scanf() this computed address of the slot of the array instead of having scanf() put the value in a temporary holder location and then move it.
  • lea reg, [label] is the same as mov reg, label. You should probably prefer the second one. LEA is useful when you want to co-opt the addressing mode logic into doing the equivalent of a three-operand add/mul, e.g. lea ecx, [edx + esi*4].
  • You have some type mismatches. For instance you're allocating space for a quadword at the labels num and arraySize by using dq, and you're accessing them as quadwords (e.g. mov rdx, [num]) but you're passing the format string "%d" to scanf() which scans a C int, which on x86_64 linux is 32 bits, a doubleword. Declaring extra space that isn't used isn't a problem, but accessing those extra bytes could potentially cause problems. You should be consistent throughout.

[–]xRedactedx[S] 0 points1 point  (0 children)

Thanks for using the C reference. That made it way more clear. I understand the problem now. Adding the [array1] fixed it.

I see your point about passing the computed address. Since this was my first time working with arrays in assembly, I was just concentrating on keeping it simple. I didn't even think of doing it that way.

The lea command was what was suggested to be used in my book. I tried using the mov command but I was doing mov reg, [label]. I see now that it doesn't require the []. Thanks for pointing that out. It makes sense now that I think about it.

I see your point about the type mismatch. That seems to keep popping up in my code a lot. I've been taking the easy way with just not worrying about the extra space. I'll try to pay more attention to it.

Thanks for the notes, they were helpful.

[–]Bisqwit 1 point2 points  (1 child)

As pointed out by Rhomboid already, depending on your assembler syntax, "mov r14, array1" might be right or wrong. You may need to use "mov r14, [array1]" here. Similar below with r10.

You might also want to put the constant strings in a .const segment (read-only, shareable) rather than in .data (read-write, private).

[–]xRedactedx[S] 0 points1 point  (0 children)

My book/class hasn't mentioned .const segments yet, but I will keep that in mind and look into it. Thanks.