我目前正在完成pintos项目,并对该项目包含的一些程序集宏有疑问
#define syscall1(NUMBER, ARG0) \
({ \
int retval; \
asm volatile \
("pushl %[arg0]; pushl %[number]; int $0x30; addl $8, %%esp" \
: "=a" (retval) \
: [number] "i" (NUMBER), \
[arg0] "g" (ARG0) \
: "memory"); \
retval; \
})
调用此宏可为仅具有一个参数的系统调用设置堆栈。我们将一个参数(系统调用号)推送到内核。我们只传递NUMBER和ARG0,我想知道[number]和[arg0](小写)的来源。我已经阅读了一些文档,但没有找到答案。希望有帮助!
谢谢
答案 0 :(得分:2)
在GCC的扩展程序集语法中,表示法 [ name ]“ constraints ”(< / b> 表达式 )说:
%rax
或16(r3)
。操作数表示法的 [ name ] 部分是可选的。如果您不提供它,则GCC会将操作数命名为0、1、2,…,因此汇编代码将使用%0 ,%1 , %2 ,... 答案 1 :(得分:1)
括在方括号中的部分是仅在ASM模板中使用的符号名称。括号中的部分是对C程序中变量名的引用。 (下面有更详细的说明)
从GCC documentation中获取ASM模板:
[ [asmSymbolicName] ] constraint (cvariablename)
asmSymbolicName
指定操作数的符号名称。将名称括在方括号中即可引用汇编程序模板中的名称(即“%[Value]”)。名称的范围是包含定义的asm语句。* 任何有效的C变量名称都是可接受的,包括周围代码中已定义的名称。 *没有两个操作数同一asm语句中的名称可以使用相同的符号名。
不使用
asmSymbolicName
时,请在汇编器模板的操作数列表中使用操作数(从零开始)的位置。例如,如果有三个输出操作数,则在模板中使用“%0”来引用第一个,第二个是“%1”,第三个是“%2”。约束
一个字符串常量,它指定对操作数放置的限制;有关详细信息,请参见约束。
输出限制必须以“ =”(覆盖现有值的变量)或“ +”(读取和写入时)开头。使用'='时,除非操作数绑定到输入,否则不要假定该位置包含输入到asm时的现有值;请参见输入操作数。在前缀之后,必须有一个或多个其他约束来描述值所在的位置(请参阅约束)。常见的限制条件包括“ r”代表寄存器,“ m”代表内存。当您列出多个可能的位置(例如,“ = rm”)时,编译器将根据当前上下文选择最有效的位置。如果您列出了asm语句允许的尽可能多的替代项,则可以允许优化器产生最佳的代码。如果必须使用特定的寄存器,但是您的机器约束不能提供足够的控制来选择所需的特定寄存器,则可以使用局部寄存器变量来提供解决方案(请参阅局部寄存器变量)。
变量名称
指定一个C值表达式来保存输出,通常是一个变量名。括号是语法的必需部分。*
...
Extended Asm - Assembler Instructions with C Expression Operands