【发布时间】:2018-09-18 07:14:35
【问题描述】:
我有一个动态分配的 2d int 数组,称为 image,以及一个称为 format 的格式字符串。 然后我使用两个嵌套的 for 循环从标准输入中获取输入,并将它们存储在二维数组中。所以我可以动态解析不同长度的输入中的整数。 例如,如果我有一个 3x3 2d 数组,我将需要使用内联 asm 将数组中的元素地址推送 9 次,并推送到格式字符串。然后我调用scanf,完成后平衡堆栈。
顺便说一句:假设数组的宽度和高度已知。
这是我在 Windows 上的代码(X64 系统,以 x32 代码编译)。它工作正常。
for (int i = 0; i < height; i++) {
for (int j = width-1; j >=0; j--) {
int tmp_addr = (int)&image[i][j];
__asm push tmp_addr;
}
int pop_size = (width+1) * 4;
__asm {
push format;
call func_scanf;
mov read_size, eax;
add esp, pop_size;
}
}
移植到Linux(X64系统,X64代码编译)时,代码不起作用。
for (int i = 0; i < height; i++) {
for (int j = width-1; j >=0; j--) {
long tmp_addr = (long)&image[i][j];
//__asm push tmp_addr;
__asm__ __volatile__(
"push %0\n\t"
::"g"(tmp_addr)
);
}
int pop_size = (width+1) * sizeof(long);
/*__asm {
push format;
call func_scanf;
mov read_size, eax;
add esp, pop_size;
}*/
__asm__ __volatile__(
"push %0\n\t"
"call *%1\n\t"
"mov %%rax,%2\n\t"
"add %3,%%rsp"
::"g"(format),"g"(func_scanf),"g"(read_size),"g"(pop_size)
:"%rax","%rsp"
);
}
执行此代码时,错误提示分段错误。 会出什么问题? 谢谢!
【问题讨论】:
-
也许我遗漏了什么,但你不能循环调用
scanf吗? -
你到底为什么要在汇编程序中编码?您正在使用
scanf(),因此效率显然不是原因 - 或者,如果是,您需要进行审查并显示证明这种编码可以产生影响的测量结果,因为坦率地说,这是非常不可能的有可衡量的性能优势。所以,你只是喜欢让你的生活更艰难吗?还有其他人需要查看代码吗?它是不可维护的(不清楚它是否可以轻松可靠地开发,但它肯定是不可维护的)。 -
C 代码中已经有很多地方存在未定义和实现定义的行为。在使用内联汇编(无论出于何种原因)进行说明之前,请学习编写正确且可维护的 C 代码。如果没有minimal reproducible example,就真的不可能知道你的代码在哪里/为什么被破坏了。
-
使用内联 asm 只调用库函数就像让 Usain Bolt 遛狗并期望它能够更快地完成任务。
-
format字符串的内容是什么?这也可能会造成一些麻烦。