红联Linux门户
Linux帮助

Linux的汇编疑惑

发布时间:2010-08-11 16:31:02来源:红联作者:wucongdonglai
最近在看Linux内核方面的东西,里面有一段是这么讲的:
在X86下,为了把栈指针的后13位有效位屏蔽掉,通过current-thread-info()函数完成,汇编代码如下:
movl $-8192, %eax
andl %eap, %eax

我看着就不明白了!这不就是在栈指针上减去8192也就是2的13次吗?除非栈指针的后13位正好都是1,不然怎么能把这后13位屏蔽掉呢?屏蔽掉后的13位应该都是为0的啊
文章评论

共有 15 条评论

  1. 于 2013-04-26 20:22:10发表:

    movl $-8192,%eax,其中$非代表当前地址,是AT&T格式汇编语言格式,代表立即数。将-8192的补码0xffffe000存入寄存器eax

  2. h.hbhychl 于 2010-10-03 18:49:51发表:

    任务中,顶一下!

  3. 木头128 于 2010-10-03 12:41:29发表:

    学习中

  4. wucongdonglai 于 2010-08-13 08:29:24发表:

    9# deepwhite
    恩,的确,是我想歪了

  5. csac2650 于 2010-08-12 23:28:43发表:

    很不错,支持楼主!
    希望和楼主可以做个朋友!

  6. yanlong938 于 2010-08-12 22:53:58发表:

    不明白。。。。。

  7. taoe29 于 2010-08-12 17:42:12发表:

    任务中,顶一下!

  8. deepwhite 于 2010-08-12 13:57:23发表:

    引用:
    5# deepwhite
    我看的是深入理解Linux内核,然后在看Linux内核设计和实现里,有相似的表述,应该不会错吧!深入理解lLinux内核里是这么说的:
    Figure 3-2 shows how the two data structures are stored in the 2- ...
    wucongdonglai 发表于 2010-8-12 11:49


    这段意思很明显啊。

    假设现在的 esp 是 0x15fa878 ,它是在两个Page组成的一个大小为8K的 thread_unio
    里面,且 thread_info 这个数据结构在这 8K 内存空间的起始位置。那么只要计算一下:

    esp & 0xFFFFE000

    就可以得到这 8K 空间起始地址了,也就是 thread_info的地址。

  9. wucongdonglai 于 2010-08-12 13:03:59发表:

    7# ahnuzq
    对哦。理解错误,呵呵,多谢啦

  10. ahnuzq 于 2010-08-12 11:58:13发表:

    让哥来告诉你吧 -8129=2的32次方减去8192就是二进制的11111111111111111110000000000000。这就是-8192在内存中的存储。这个值再与上 $sp 不就是只保留上面的19位吗,不也就是一8k也就是两页的 最低地址吗 明白了吗

  11. wucongdonglai 于 2010-08-12 11:49:04发表:

    5# deepwhite
    我看的是深入理解Linux内核,然后在看Linux内核设计和实现里,有相似的表述,应该不会错吧!深入理解lLinux内核里是这么说的:
    Figure 3-2 shows how the two data structures are stored in the 2-page (8 KB) memory area. The thread_info structure resides at the beginning of the memory area, and the stack grows downward from the end. The figure also shows that the tHRead_info structure and the task_struct structure are mutually linked by means of the fields task and tHRead_info, respectively.
    Figure 3-2. Storing the thread_info structure and the process kernel stack in two page frames
    [attach]31786[/attach]
    ……
    The close association between the thread_info structure and the Kernel Mode stack just described offers a key benefit in terms of efficiency: the kernel can easily obtain the address of the thread_info structure of the process currently running on a CPU from the value of the esp register. In fact, if the thread_union structure is 8 KB (213 bytes) long, the kernel masks out the 13 least significant bits of esp to obtain the base address of the thread_info structure; on the other hand, if the thread_union structure is 4 KB long, the kernel masks out the 12 least significant bits of esp. This is done by the current_thread_info( ) function, which produces assembly language instructions like the following:
    movl $0xffffe000,%ecx /* or 0xfffff000 for 4KB stacks */
    andl %esp,%ecx
    movl %ecx,p
    After executing these three instructions, p contains the tHRead_info structure pointer of the process running on the CPU that executes the instruction.

    这里面esp寄存器是存放着栈指针的,以那图做例子:在那图中的栈指针的位置是0x015fa878,而thread-info的位置是在于0x015fa000,它通过那段汇编指令,也就是0x015fa878减去0x00002000,得到的是0x015f8878啊,怎么都不可能是0x015fa000啊?所以我就疑惑嘛

  12. deepwhite 于 2010-08-12 09:18:13发表:

    我查了一下,多数的资料里面都说,栈指针的底13位是thread_info的地址,这样的话将 栈地址减去 8192得到的是 thread_info,这样才说的通。

    你是不是看错了,或者理解错了,还是你看的书有问题?

  13. wucongdonglai 于 2010-08-12 08:45:14发表:

    3# shenhao0129
    完整的是这样的:
    假定栈的大小为8KB,也就是说thread-info和栈所占的空间为8KB,栈从高位往低位增长!X86通过把栈指针的后13个有效位屏蔽掉来计算thread-info的偏移!该操作通过current-thread-info()函数完成,汇编代码如下:
    movl $-8192, %eax
    andl %eap, %eax

    其实这讲的是内核中由于X86没有设置一个专门的寄存器来存放指向进程描述符的指针,所以就只能通过栈指针来找到thread-info,然后在thread-info的task域找到进程描述符的地址!具体实现就是把那栈指针的后13位有效位给屏蔽掉!而我想问的也就是:这段汇编在我的理解中,只是把栈指针-8192,而不是屏蔽掉后13位有效位!对这比较不理解

  14. shenhao0129 于 2010-08-11 18:34:24发表:

    刚才找了一下资料,发现栈区都是页对齐的,并且是屏蔽低13位的。你给出来的那部分资料太简略了点,不知道你的是个什么情况

  15. ecfarther1 于 2010-08-11 17:12:11发表:

    好多东西需要学习的哦