gpt4 book ai didi

c - 内联汇编,进入中断

转载 作者:太空宇宙 更新时间:2023-11-04 06:35:55 24 4
gpt4 key购买 nike

美好的一天。我遇到了一个我几天都无法解决的问题。当我试图用 C 语言编译这个函数时出现错误。

void GetInInterrupt(UChar Interrupt)
{
//asm volatile(".intel_syntax noprefix");
asm volatile
(
"movb %0, %%al\n"
"movb %%al, 1(point)\n"
"point:\n"
"int $0\n"
: /*output*/ : "r" (Interrupt) /*input*/ : /*clobbered*/
);
//asm volatile(".att_syntax noprefix");
}

我从 gas 得到的消息如下:

Error: junk '(point)' after expression

据我所知,第二行的指针有问题,但不幸的是我无法自行解决。


谢谢你的帮助。

最佳答案

如果你会使用 C++,那么这个:

template <int N> static inline void GetInInterrupt (void)
{
__asm__ ("int %0\n" : "N"(N));
}

会做。如果我像这样使用该模板:

GetInInterrupt<123>();
GetInInterrupt<3>();
GetInInterrupt<23>();
GetInInterrupt<0>();

创建以下目标代码:

   0:   cd 7b                   int    $0x7b
2: cc int3
3: cd 17 int $0x17
5: cd 00 int $0x0

这几乎是最优的(即使对于 int3 情况,这是断点操作)。如果操作数超出 0..255 范围,它还会创建一个编译时警告,因为 N 约束只允许这样做。

编辑:当然,普通的旧 C 风格宏也可以工作:

#define GetInInterrupt(arg) __asm__("int %0\n" : : "N"((arg)) : "cc", "memory")

创建与 C++ 模板化函数相同的代码。由于 int 的行为方式,最好将屏障语义告知编译器(通过 "cc"、"memory" 约束),以确保它嵌入内联程序集时不会尝试重新排序指令。

显然,两者的局限性在于中断号必须是编译时常量。如果您绝对不想那样,则创建一个 switch() 语句,例如在 BOOST_PP_REPEAT() 的帮助下覆盖所有 255 个案例是比自修改代码更好的选择,例如:

#include <boost/preprocessor/repetition/repeat.html>

#define GET_INTO_INT(a, INT, d) case INT: GetInInterrupt<INT>(); break;

void GetInInterrupt(int interruptNumber)
{
switch(interruptNumber) {
BOOST_PP_REPEAT(256, GET_INTO_INT, 0)
default:
runtime_error("interrupt Number %d out of range", interruptNumber);
}
}

可以在纯 C 中完成(当然,如果您更改纯 __asm__ 的模板化函数调用)——因为 boost 预处理器库 依赖于 C++ 编译器……gcc 4.7.2 为此创建了以下代码:


GetInInterrupt:
.LFB0:
cmpl $255, %edi
jbe .L262
movl %edi, %esi
xorl %eax, %eax
movl $.LC0, %edi
jmp runtime_error
.p2align 4,,10
.p2align 3
.L262:
movl %edi, %edi
jmp *.L259(,%rdi,8)
.section .rodata
.align 8
.align 4
.L259:
.quad .L3
.quad .L4
[ ... ]
.quad .L258
.text
.L257:
#APP
# 17 "tccc.c" 1
int $254

# 0 "" 2
#NO_APP
ret
[ ... accordingly for the other vectors ... ]

请注意,如果您执行上述操作...编译器(gcc 到 4.8 及包括 4.8)不够智能到无法优化 switch(),即即使你说 static __inline__ ... 它也会创建 GetInInterrupt(3) 的完整跳转表版本,而不仅仅是一个内联的 int3更简单的实现也是如此。

关于c - 内联汇编,进入中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15042996/

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