Хочу сделать обращение к массиву (со смещением) через вставку на ассемблере.
Код без ассемблера выглядит просто и работает:
#include <stdio.h>
#include <stdlib.h>
const unsigned int SIZE = 131049;
const unsigned int INDEX = 10;
int main()
{
char *arr = (char*)malloc(SIZE * sizeof(char));
arr[INDEX] = 0x5f;
unsigned int x = arr[INDEX];
printf("Array adress: %x\nArray adress + INDEX: %x\nResult: %x\n", (void *)arr, ((void *)arr) + INDEX, x);
}
Код на ассемблере падает с segmentation fault:
int main()
{
char *arr = (char*)malloc(SIZE * sizeof(char));
arr[INDEX] = 0x5f;
unsigned int newAddress = 0;
unsigned int x = 0;
asm volatile (
"movl %[INDEX], %%eax \n"
"addl %[arr], %%eax \n"
"movl %%eax, %[newAddress] \n"
"movl (%%eax), %[x] \n"
: [newAddress] "=r" (newAddress), [x] "=r" (x)
: [INDEX] "r" (INDEX), [arr] "m" (arr)
: "eax", "memory"
);
printf("Array adress: %x\nArray adress + INDEX: %x\nResult: %x\n", (void *)arr, newAddress, x);
}
При SIZE < 131049 оба примера работают одинаково. Цифра выведена экспериментально.
Что я делаю не так во втором примере?
PS:
Похоже что это почти 2^17 (131072). Догадываюсь что это как то связано с размерностью регистров, но знаний не хватает чтобы исправить код.
PSPS:
Собираю просто через g++.