Передача массива в качестве аргумента функции x86 из C - PullRequest
0 голосов
/ 25 мая 2019

У меня есть файл bmp, и я читаю его в функции c и сохраняю значения пикселей как целое число без знака. Я хочу передать этот целочисленный массив без знака в x86, но у меня ничего не получается. Вот мой код c:

У меня есть эти свойства:

extern int func(char *a);
unsigned char* image;

И мой основной метод:

int main(void){
  image = read_bmp("cur-03.bmp");
  int result = func(image);
  printf("\n%d\n", result);
  return 0;
}

Я проверяю свой массив, и он имеет истинные значения.

Вот мой код носа:

section .text
global  func

func:
    push ebp
    mov ebp, esp
    mov ecx , DWORD [ebp+8] ;address of *a to eax


    pop ebp
    ret

section .data
    values: TIMES   255         DB      0   

Я ожидаю, что ecx будет иметь первый элемент моего массива, но вместо этого я получу 1455843040 И адрес, вероятно?

А вот read_bmp:

unsigned char* read_bmp(char* filename)
{
    int i;
    FILE* f = fopen(filename, "rb");
    unsigned char info[54];
    fread(info, sizeof(unsigned char), 54, f); // read the 54-byte header

    // extract image height and width from header
    int width = *(int*)&info[18];
    int height = *(int*)&info[22];
    int heightSign =1;
    if(height<0){
        heightSign = -1;
    }

    int size = 3 * width * abs(height);
    printf("size is %d\n",size );
    unsigned char* data = malloc(size); // allocate 3 bytes per pixel
    fread(data, sizeof(unsigned char), size, f); // read the rest of the data at once
    fclose(f);

    return data;
}

Моя конечная цель - взять элементы массива (который находится в интервале от 0 до 255) и соответствующее значение в моем массиве размером 255 байт. Например, если первый элемент равен 55 в моем первом массиве, я увеличу 55-й элемент на единицу в массиве размером 255 байт. Поэтому мне нужен доступ к элементам массива, которые я передаю с.

1 Ответ

2 голосов
/ 25 мая 2019

Когда у вас есть C прототип extern int func(char *a);, вы передаете указатель на массив символов a в стеке. Ваш код сборки делает это:

push ebp
mov ebp, esp
mov ecx , DWORD [ebp+8] ;address of *a to eax

EBP + 8 - это операнд памяти (в стеке), в котором адрес a был помещен вызывающей функцией. В итоге вы получили указатель на a (1455843040) из стека. Что вам нужно сделать, это еще раз разыменовать указатель, чтобы получить отдельные элементы. Вы можете сделать это с помощью кода:

push ebp
mov ebp, esp
mov eax , DWORD [ebp+8] ; Get address of character array into EAX
mov cl, [eax]           ; Get the first byte at that address in EAX. 

Чтобы получить второй байт в массиве:

mov cl, [eax+1]         ; Get the second byte at that address in EAX.

И так далее.

...