I just started learning assembly for a contest and I am using intel-syntax
inline assembly.
Recentlly I've learned how to access global C
variable's in assembly using <type> ptr[rip + <variable name>]
syntax. (for example in the mov
command)
I tried to do the same thing with arrays and by adding a + <n * size of one element>
after the variable name, I can access the nth element of the C
array.
But I decided to write a program that iterates over an array and calculate the sum.
Here is the code:
#include <stdio.h>
unsigned long long array[10];
int main()
{
array[0] = 1;
array[1] = 1;
array[2] = 1;
array[3] = 1;
array[4] = 1;
array[5] = 1;
array[6] = 1;
array[7] = 1;
array[8] = 1;
array[9] = 1;
unsigned long long element_len = sizeof(*array);
unsigned long long len = sizeof(array);
unsigned long long sum = 0;
asm(R"(
.intel_syntax noprefix;
mov rcx, 0;
mov r8, 0;
loop:
add rcx, qword ptr[rip + array + r8];
add r8, rax;
cmp r8, rbx;
jb loop;
.att_syntax noprefix;
)"
: "=c" (sum) // outputs
: "a" (element_len), "b" (len) // inputs
: "r8" // clobbers
);
printf("%llu\n", sum);
return 0;
}
But because of that + r8
; the compiler gives me this error (works fine when there is some constant value instead of r8
)
$ gcc sum.c
sum.c: Assembler messages:
sum.c:61: Error: `qword ptr[rip+array+r8]' is not a valid base/index expression
I am using Kubuntu (technically Ubuntu) 20.04 on a 64-bit Intel processor and compiling the program using gcc 9.3.0
.
EDIT: Fixed by @Jester's comment.
asm(R"(
.intel_syntax noprefix;
mov rcx, 0;
mov r8, 0;
lea rdx, [rip+array];
loop:
add rcx, [rdx+r8];
add r8, rax;
cmp r8, rbx;
jb loop;
.att_syntax noprefix;
)"
: "=c" (sum) // outputs
: "a" (element_len), "b" (len) // inputs
: "r8" , "rdx"// clobbers
);