struct task_struct * get_current(void)函数的解释--help!!

arcsiny 2003-05-07 11:22:04
static inline struct task_struct * get_current(void)
{
struct task_struct *current;
__asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL));
return current;
}
堆栈指针寄存器esp与“~8191UL"相与可以得到当前进程的起始地址。
请问esp里是什么内容? ~8191UL 如何解释?UL?
谢谢!
...全文
310 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
arcsiny 2003-05-07
  • 打赏
  • 举报
回复
多谢了
基本明白一点
不过还有 UL 是什么意思?
oldmaize 2003-05-07
  • 打赏
  • 举报
回复
From
kernel 2.2 when a process is created its task_struct and its kernel
mode stack are placed together in two contiguos page frames (so 8KB).
They are organized "with the task_struct at the beginning and the
stack growing from the end downwards" as you correctly said. Now when
we want to obtain task descriptor (address of task_struct) we use
%esp. Why? Because if you're in kernel mode %esp is the kernel mode
stack pointer. Now you can easily notice that zeroing the last %esp 13
bytes gives you exactly what you need since it will point to the
beginning of the first page frame (where task_struct is).
Now, with this in mind, it's easy to understand get_current().

This is inline asm syntax.

asm ( assembler template
: output operands (optional)
: input operands (optional)
: list of clobbered registers (optional)
);

When you see "0" in input operands in get_current it means it's the
same of first argument. "=r" stands for register and so the output
operand is to be stored in a register. Now get_current() should appear
simple. It loads ~8191UL in current and then ANDs it with %esp
storing the result in current.
oldmaize 2003-05-07
  • 打赏
  • 举报
回复
get_current() is a routine for getting access to the task_struct of the currently executing task. It uses the often confusing inline assembly features of GCC to perform this, as follows :

| __asm__(

This signifies a piece of inline assembly that the compiler must insert into its output code. The __asm__ is the same as asm, but can't be disabled by command line flags.

| "andl %%esp,%0

"%%" is a macro that expands to a "%".
"%0" is a macro that expands to the first input/output specification.

So in this case, it takes the stack pointer (register %esp) and ANDs it into a register that contains 0xFFFFE000, leaving the result in that register.

Basically, the task's task_struct and a task's kernel stack occupy an 8KB block that is 8KB aligned, with the task_struct at the beginning and the stack growing from the end downwards. So you can find the task_struct by clearing the bottom 13 bits of the stack pointer value.

| ; "

The semicolon can be used to separate assembly statements, as can the newline character escape sequence ("\n").

| :"=r" (current)

This specifies an output constraint (all of which occur after the first colon, but before the second). The '=' also specifies that this is an output. The 'r' indicates that a general purpose register should be allocated such that the instruction can place the output value into it. The bit inside the brackets - 'current' - is the intended destination of the output value (normally a local variable) once the C part is returned to.

| : "0" (~8191UL));

This specifies an input constraint (all of which occur after the second colon, but before the third). The '0' references another constraint (in this case, the first output constraint), saying that the same register or memory location should be used for both. The '~8191UL' inside the brackets is a constant that should be loaded into the register allocated for the output value before using the instructions inside the asm block.

See also the gcc info pages, Topic "C Extensions", subtopic "Extended Asm".

代码下载链接: https://pan.quark.cn/s/b27638adc362 在工业自动化监控领域中,WinCC 被视为一种常用的可视化软件,其功能在于构建人机界面(HMI)以及SCADA系统。本资料将阐释在WinCC环境下如何构建一个展现管道中流体流动的动态效果,此功能主要通过C动作脚本来完成。在此过程中,我们需要构建两个矩形,分别标记为 rec1 和 rec2。这两个矩形的高度相等,但 rec1 的宽度要小于 rec2。在具体实施时,rec1 将作为展示流体运动的可见单元,而 rec2 则作为辅助元素,尽管其“显示”属性被设为关闭,但在程序执行期间,其属性参数对流体动画的表现起着决定性作用,因为 rec2 与 rec1 的宽度差将决定流体每次移动的长度。 随后,我们需要将 rec1 和 rec2 整合为一个自定义对象。在自定义对象的属性配置中,应包含 rec1.Left、rec1.Width、rec1.Visible 和 rec2.Width 这些核心属性。这些属性将有助于在C脚本中精确控制对象的位置和可见状态,以达成流体运动的视觉效果。同时,用户可根据实际需求增加其他属性,以增强自定义对象的功能性。 在自定义对象的C脚本部分,我们设定了一个周期为“250ms”的触发器。该脚本的核心职责是计算并更新流体块的位置。借助 GetPropBOOL、GetPropWord 和 GetLeft 函数,我们可以获取对象的当前状态,涵盖其可见性、位置及宽度等参数。在循环操作中,流体块(rec1)将向右移动 rec2 - rec1 的距离,一旦流体块移出显示范围(即 rec1 的右边界达到或超过 rec2 的左边界),它将重新回到起始位置,从而形成流体持续流动的模...

23,223

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧