【问题标题】:Passing an array as argument to a x86 function from C将数组作为参数从 C 传递给 x86 函数
【发布时间】:2019-05-25 11:39:40
【问题描述】:

我有一个 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;
}

我检查了我的数组,它有真实的值。

这是我的 nasm 代码:​​

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,我将在 255 字节大小的数组中将第 55 个元素递增一个。所以我需要访问从 c 传递的数组元素。

【问题讨论】:

  • 可能是地址? - 是的,数组会衰减为指向它在该上下文中的第一个元素的指针。你没有数组。内存是如何在 read_bmp() 中分配的?
  • 用C写一个简单的func,编译一下看看汇编器是什么。将其用作函数的模板。
  • 你怎么知道这张图片的大小?!
  • 我的集合中的所有图像都具有相同的大小
  • OT: 1) 始终检查 (!=NULL) 来自 fopen() 的返回值,以确保操作成功。如果不成功,请调用perror() 将您的错误消息和系统认为错误发生的文本原因输出到stderr。 2) 在调用fread() 时,始终将返回值与第三个参数进行比较,以确保操作成功。如果不成功,如上调用perror()

标签: c assembly x86 nasm calling-convention


【解决方案1】:

当你有一个 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.

等等。

【讨论】:

    猜你喜欢
    • 2021-09-15
    • 2012-12-07
    • 1970-01-01
    • 2013-01-27
    • 2015-06-09
    • 2016-11-06
    • 2012-11-23
    相关资源
    最近更新 更多