gpt4 book ai didi

c - X86 程序集 - 处理数组类型参数

转载 作者:太空宇宙 更新时间:2023-11-03 23:33:07 25 4
gpt4 key购买 nike

我目前正在编写一个简单的 C 编译器,它将 .c 文件作为输入并生成汇编代码(X86、AT&T 语法)。我很难传递数组类型的参数并为其生成正确的汇编代码。这是我的输入:

int getIndexOne(int tab[]){
return tab[1];
}

int main_test(void){
int t[3];
t[0] = 0;
t[1] = 1;
t[2] = 2;
return getIndexOne(t);
}

一个相当简单的测试。这是我的输出:

getIndexOne:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 16
movl %esp, %ebp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl %edi, -24(%ebp)
movl $1, %eax
movl -24(%ebp, %eax, 8), %eax #trouble over here
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size getIndexOne, .-getIndexOne


falsemain:
.LFB1:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 16
movl %esp, %ebp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
pushl %ebx
subl $120, %esp
movl $2, -32(%ebp)
movl $0, %eax
movl $0, -24(%ebp, %eax, 8)
movl $1, %eax
movl $1, -24(%ebp, %eax, 8)
movl $2, %eax
movl $2, -24(%ebp, %eax, 8)
leal -24(%ebp, %eax, 8), %eax
movl %eax, %edi
call getIndexOne
addl $120, %esp
popl %ebx
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size main_test, .-main_test

我无法访问传递的地址(leal 指令)的内容。任何帮助将非常感激。PS:不要担心我的整数的大小,由于其他原因,它们被设置为 8 个字节而不是 4 个字节。

最佳答案

有两个问题,第一个是在为调用 getIndexOne 设置堆栈时:

movl    $2, %eax
movl $2, -24(%ebp, %eax, 8)
leal -24(%ebp, %eax, 8), %eax ##<== EAX still holds value of 2!
movl %eax, %edi ##<== wrong address for start of array

您没有在 MOV 命令后清除 EAX 寄存器的内容,因此您要放入 EDI 的地址> 函数调用的注册不是指向数组的开头,而是数组的最后一个元素(即元素值为 2 的第二个索引)。

第二个问题出现在您的 getIndexOne 函数中:

movl    %edi, -24(%ebp)
movl $1, %eax
movl -24(%ebp, %eax, 8), %eax

您已将地址存储在堆栈中。这很好,但这也意味着当您从堆栈中检索值时,您将获得一个返回指针,然后必须第二次取消引用该指针。你现在正在做的是你只是从堆栈上的帧指针读回一个值偏移量......这不是数组中的值,因为你没有取消引用你存储在堆栈中的指针。换句话说,如果必须将指针存储在堆栈上,则应将其更改为以下内容(我认为这不是最有效的方法,因为该值已经在 EDI 中,但无论如何):

movl    %edi, -24(%ebp)           ##<== store pointer to the array on the stack
movl $1, %eax
movl -24(%ebp), %ecx ##<== get the pointer back from the stack
movl (%ecx, %eax, 8), %eax ##<== dereference the pointer

作为旁注,虽然我不确定您的编译器是如何工作的,但我确实认为您使用加载到数组元素中的值同时索引到数组中有点可怕......如果正在加载的值与数组索引不匹配,这会造成相当大的破坏......我猜这是你在两个值匹配时尝试进行的某种优化?

关于c - X86 程序集 - 处理数组类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10637989/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com