Iva*_*anq 7 c optimization icc
我正在制作一个需要同时运行多个任务的应用程序。我不能使用线程等,因为应用程序应该在没有任何操作系统的情况下工作(即直接从引导扇区)。使用 x86 任务看起来有点矫枉过正(在逻辑和性能方面)。因此,我决定自己实现一个任务切换实用程序。我会保存处理器状态,调用任务代码,然后恢复以前的状态。所以我必须从内联汇编中进行调用。
下面是一些示例代码:
#include <stdio.h>
void func() {
printf("Hello, world!\n");
}
void (*funcptr)();
int main() {
funcptr = func;
asm(
"call *%0;"
:
:"r"(funcptr)
);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它在 icc 下完美编译,没有选项,gcc 和 clang 并产生“Hello,world!” 运行时。但是,如果我用 编译它icc main.c -ipo
,它会出现段错误。
我反汇编了生成的代码icc main.c
并得到以下内容:
0000000000401220 <main>:
401220: 55 push %rbp
401221: 48 89 e5 mov %rsp,%rbp
401224: 48 83 e4 80 and $0xffffffffffffff80,%rsp
401228: 48 81 ec 80 00 00 00 sub $0x80,%rsp
40122f: bf 03 00 00 00 mov $0x3,%edi
401234: 33 f6 xor %esi,%esi
401236: e8 45 00 00 00 callq 401280 <__intel_new_feature_proc_init>
40123b: 0f ae 1c 24 stmxcsr (%rsp)
40123f: 48 c7 05 f6 78 00 00 movq $0x401270,0x78f6(%rip) # 408b40 <funcptr>
401246: 70 12 40 00
40124a: b8 70 12 40 00 mov $0x401270,%eax
40124f: 81 0c 24 40 80 00 00 orl $0x8040,(%rsp)
401256: 0f ae 14 24 ldmxcsr (%rsp)
40125a: ff d0 callq *%rax
40125c: 33 c0 xor %eax,%eax
40125e: 48 89 ec mov %rbp,%rsp
401261: 5d pop %rbp
401262: c3 retq
401263: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
401268: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
40126f: 00
0000000000401270 <func>:
401270: bf 04 40 40 00 mov $0x404004,%edi
401275: e9 e6 fd ff ff jmpq 401060 <puts@plt>
40127a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
Run Code Online (Sandbox Code Playgroud)
另一方面,icc main.c -ipo
产量:
0000000000401210 <main>:
401210: 55 push %rbp
401211: 48 89 e5 mov %rsp,%rbp
401214: 48 83 e4 80 and $0xffffffffffffff80,%rsp
401218: 48 81 ec 80 00 00 00 sub $0x80,%rsp
40121f: bf 03 00 00 00 mov $0x3,%edi
401224: 33 f6 xor %esi,%esi
401226: e8 25 00 00 00 callq 401250 <__intel_new_feature_proc_init>
40122b: 0f ae 1c 24 stmxcsr (%rsp)
40122f: 81 0c 24 40 80 00 00 orl $0x8040,(%rsp)
401236: 48 8b 05 cb 2d 00 00 mov 0x2dcb(%rip),%rax # 404008 <funcptr_2.dp.0>
40123d: 0f ae 14 24 ldmxcsr (%rsp)
401241: ff d0 callq *%rax
401243: 33 c0 xor %eax,%eax
401245: 48 89 ec mov %rbp,%rsp
401248: 5d pop %rbp
401249: c3 retq
40124a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
Run Code Online (Sandbox Code Playgroud)
因此,虽然-ipo
没有删除funcptr
变量(参见地址 401236),但它确实删除了赋值。我猜 icc 注意到它func
不是从 C 代码中调用的,因此可以安全地删除它,因此funcptr
允许包含垃圾。但是,它没有注意到我是func
通过程序集间接调用的。
"r"(funcptr)
为"r"(func)
作品,但我无法对特定功能进行硬编码(参见背景)。funcptr
和/或func
在内联汇编块之前和/或之后没有帮助,因为 icc 只是 inlines printf("Hello, world!\n");
。a value of type "void (*)()" cannot be assigned to an entity of type "volatile void (*)()"
Run Code Online (Sandbox Code Playgroud)
volatile
到几乎所有其他单词也无济于事。func
和/或funcptr
到其他源文件,然后将它们链接在一起并没有帮助。我做错了什么还是icc错误?如果是前者,我该如何修复代码?如果是后者,是否有任何解决方法,我应该报告错误吗?
$ icc --version
icc (ICC) 19.1.0.166 20191121
Copyright (C) 1985-2019 Intel Corporation. All rights reserved.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
109 次 |
最近记录: |