gpt4 book ai didi

c - 尝试打印 double 时程序崩溃(但其他类型都可以)

转载 作者:行者123 更新时间:2023-11-30 20:10:27 25 4
gpt4 key购买 nike

我正在尝试从汇编代码 (Linux x86-64) 调用 C 函数。在汇编代码中,类型由 3 LSB 编码。 C 函数的目的只是为了轻松打印键入的值。这是函数:

int print(long i) {
int type = i & 7;
long val = i >> 3;
double c;
switch(type) {
case 0:
printf("%d\n", val);
break;
case 1:
if (!val)
printf("false\n");
else if (val == 1)
printf("true\n");
else if (val == 2)
printf("nil\n");
break;
case 2:
printf("%s\n", (char*)(val + 8));
break;
case 6:
c = *(double*) val;
//printf("%d\n", (int)c); /* no seg fault */
//printf("%f\n", 1.0); /* seg fault */
printf("%f\n", c); /* seg fault */
break;
}
return 1;
}

到目前为止,我一直在使用字符串指针,没有出现任何问题,所以我知道这不是内存问题,但这是我第一次使用 %xmm 寄存器,所以我可能正在做一些事情那里错了。这是相关的调用片段:

    movsd   _DB1(%rip), %xmm4
movsd _DB2(%rip), %xmm5
addsd %xmm5, %xmm4
movsd %xmm4, (%r12)
leaq 6(, %r12, 8), %rdi
addq $8, %r12
call print
##### ... #####
.data
_DB1:
.double 2
_DB2:
.double 3

%r12 指向堆中分配的内存。最奇怪的是,如果我在调用 printf 之前将 double 转换为整数,则不会出现段错误(取消注释案例 6 中的行并注释下面的行)并且它会输出正确的结果(5)。在调试过程中,我发现段错误发生在 printf 函数的子例程中,我看不到代码。另外,即使我定义了一个随机 double ,我也无法打印它。

此时,我们将不胜感激任何帮助,谢谢。

最佳答案

代码片段的行为取决于如何将指向 double 的指针和字符串编码为 longi 以及其他注意事项。它非常不便携。

您计算 long val = i >> 3;,它对 i 的负值具有实现定义的行为,并生成带有 0 的指针值> 或 1 高位,稍后转换为 (double*)(char*) 时。虽然指针表示中的一些高位在常见架构上被忽略,但依赖这种行为是不安全的,并且在 32 位英特尔 PC 上会失败。确保指针(至少)在 8 字节边界上对齐并屏蔽低位或以其他方式在转换为 (double*) 之前调整值可能是一个更好的主意>(字符*)

如果 long 小于 void*,使用 uintptr_t 而不是 long 也更便携>,与 64 位 Windows 系统上的情况一样。

关于c - 尝试打印 double 时程序崩溃(但其他类型都可以),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45563917/

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