kirill89
@kirill89

Как передать память из Си в ассемблер?

Хочу сделать обращение к массиву (со смещением) через вставку на ассемблере.

Код без ассемблера выглядит просто и работает:

#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++.
  • Вопрос задан
  • 600 просмотров
Решения вопроса 1
  • jcmvbkbc
    @jcmvbkbc
    http://dilbert.com/strip/1998-08-24
    Неправильный констрейнт:
    [arr] "m" (arr)

    вместо "m" должно быть "r". "m" означает память на которую ссылается выражение, "r" -- само выражение.
    Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы