名字不能取太长 2023-01-24 13:51 采纳率: 78%
浏览 67
已结题

阅读内联汇编时遇到了一些问题

以下是一个宏函数,包含了一段内联汇编,用于配置中断描述符表的中断门和陷阱门:

#define _set_gate(gate_selector_addr,attr,ist,code_addr)    \
do                                \
{    unsigned long __d0,__d1;                \
    __asm__ __volatile__    (    "movw    %%dx,    %%ax    \n\t"    \
                    "andq    $0x7,    %%rcx    \n\t"    \
                    "addq    %4,    %%rcx    \n\t"    \
                    "shlq    $32,    %%rcx    \n\t"    \
                    "addq    %%rcx,    %%rax    \n\t"    \
                    "xorq    %%rcx,    %%rcx    \n\t"    \
                    "movl    %%edx,    %%ecx    \n\t"    \
                    "shrq    $16,    %%rcx    \n\t"    \
                    "shlq    $48,    %%rcx    \n\t"    \
                    "addq    %%rcx,    %%rax    \n\t"    \
                    "movq    %%rax,    %0    \n\t"    \
                    "shrq    $32,    %%rdx    \n\t"    \
                    "movq    %%rdx,    %1    \n\t"    \
                    :"=m"(*((unsigned long *)(gate_selector_addr)))    ,                    \
                     "=m"(*(1 + (unsigned long *)(gate_selector_addr))),"=&a"(__d0),"=&d"(__d1)        \
                    :"i"(attr << 8),                                    \
                     "3"((unsigned long *)(code_addr)),"2"(0x8 << 16),"c"(ist)                \
                    :"memory"        \
                );                \
}while(0)

请问这个内联汇编中输出部分的&修饰符是什么意思?在翻阅gcc手册时理解的是&修饰符表示修饰的操作数输入和输出不能使用同一个寄存器,但是看这个代码时候感觉理解错了,希望有人能仔细解释一下"=&a"(__d0),"=&d"(__d1)的意思。
另一个问题是输入部分的"3"和"2"是什么意思?是表示输入部分的第3个操作数吗?
最后希望能解释以下这段汇编的输入输出是什么,汇编代码在做什么?

  • 写回答

3条回答 默认 最新

  • 社区专家-Monster-XH 2023-01-24 14:42
    关注

    一:&修饰符在这里表示该操作数既是输入也是输出,它可以保证该操作数在输入和输出之间的值相同。
    二:"=&a"(__d0),"=&d"(__d1) 表示 __d0 和 __d1 是输出操作数,并且它们的值来自寄存器 ax 和 dx。 & 表示该操作数既是输入也是输出,它可以保证该操作数在输入和输出之间的值相同。
    三:"3"((unsigned long *)(code_addr))是表示第3个输入操作数,"2"(0x8 << 16)表示第2个输入操作数。
    四:这段汇编的输入是 "i"(attr << 8), "3"((unsigned long *)(code_addr)),"2"(0x8 << 16),"c"(ist)。其中,attr << 8 是一个属性值, (unsigned long *)(code_addr) 是代码地址,0x8 << 16 是代码段选择器,ist 是中断栈指针。

    输出是 "=m"(*((unsigned long )(gate_selector_addr))), "=m"((1 + (unsigned long *)(gate_selector_addr))),"=&a"(__d0),"=&d"(__d1)。其中, *((unsigned long *)(gate_selector_addr)) 和 *(1 + (unsigned long *)(gate_selector_addr)) 是中断描述符表的对应位置, __d0 和 __d1 是辅助寄存器。
    五:汇编代码的目的是将输入的属性值,中断栈指针,代码段选择器和代码地址组合成一个64位的值,并将其存储到中断描述符表的对应位置中。具体来说,它通过对寄存器 ax,dx,cx进行操作,将属性值,代码段选择器和代码地址组合成一个64位值,然后将该值存储到中断描述符表的对应位置中。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 1月31日
  • 已采纳回答 1月24日
  • 创建了问题 1月24日

悬赏问题

  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误