Linux 一些内核ARM代码

Linux 一些内核ARM代码,linux,linux-kernel,arm,system-calls,Linux,Linux Kernel,Arm,System Calls,我在阅读一些ARM内核源代码,直到偶然发现以下函数:- 314 #define __get_user_asm_byte(x, addr, err) \ 315 __asm__ __volatile__( \ 316 "1: " TUSER(ldrb) " %1,[%2],#0\n" \ 317

我在阅读一些ARM内核源代码,直到偶然发现以下函数:-

314 #define __get_user_asm_byte(x, addr, err)                       \
315         __asm__ __volatile__(                                   \
316         "1:     " TUSER(ldrb) " %1,[%2],#0\n"                   \
317         "2:\n"                                                  \
318         "       .pushsection .fixup,\"ax\"\n"                   \
319         "       .align  2\n"                                    \
320         "3:     mov     %0, %3\n"                               \
321         "       mov     %1, #0\n"                               \
322         "       b       2b\n"                                   \
323         "       .popsection\n"                                  \
324         "       .pushsection __ex_table,\"a\"\n"                \
325         "       .align  3\n"                                    \
326         "       .long   1b, 3b\n"                               \
327         "       .popsection"                                    \
328         : "+r" (err), "=&r" (x)                                 \
329         : "r" (addr), "i" (-EFAULT)                             \
330         : "cc")
调用上下文如下所示:-

299 #define __get_user_err(x, ptr, err)                                     \
300 do {                                                                    \
301         unsigned long __gu_addr = (unsigned long)(ptr);                 \
302         unsigned long __gu_val;                                         \
303         __chk_user_ptr(ptr);                                            \
304         might_fault();                                                  \
305         switch (sizeof(*(ptr))) {                                       \
306         case 1: __get_user_asm_byte(__gu_val, __gu_addr, err);  break;  \
现在我有一些疑问,我想澄清一下上面的臂组件

  • 函数
    \u get\u user\u asm\u byte
    在做什么?我可以看到r3被复制到r0中,值0被移动到r1中。之后它是否分支到偏移量0x2b
  • 函数试图做什么?从第328行开始的
    “+r”(err)、“=&r”(x)
    是什么意思
  • 什么是.pushsection和.popsection
  • 为什么为内核编写的ARM汇编在语法上如此不同(汇编程序使用了什么?为什么有
    %
    而不是
    r
    ?)

  • 首先,正如评论所指出的,语法是标准的gcc内联汇编语法(即
    +r
    =&r
    %


    唯一的ARM特定项是使用
    ldrt
    或MMU域;这在现代ARM CPU支持域中是有条件的。转换后的加载/存储变体对较旧的CPU应用用户模式访问。

    至于4。-如果您告诉GCC编译而不是组装(
    -S
    选项),您可以找到一种汇编语法也就是说,汇编程序应用程序是GAS。
    %0
    不是
    r0
    2b
    不是
    0x2b
    。请阅读。@CL。谢谢你的帮助!如果你能把它作为答案添加进来,我可以接受。