第三周学习笔记
第三周学习笔记
2018-10-24
- C代码中嵌入汇编代码语法
asm("statements": output_regs:input_regs:clobbered_regs);
汇编语句模板 输出 输入 破坏描述部分
eg:
今日问题:
- eax的值到底存数据还是地址 居然百度都没搜到答案。。。反思自己连百度都不会用
- 破坏描述部分是什么?
有时在进行某些操作时,除了要用到进行数据输入和输出的寄存器外,还要使用多个寄存器来保存中间计算结果,这样就难免会破坏原有寄存器的内容。如果希望GCC在编译时能够将这一点考虑进去。那么你就可以在“破坏描述部分”声明这些寄存器或内存。
这种情况一般发生在一个寄存器出现在“汇编语句模板”,但却不是由输入或输出操作表达式所指定的,也不是在一些输入或输出操作表达式使用"r"、"g"约束时由GCC为其选择的,同时此寄存器被“汇编语句模板”中的指令修改,而这个寄存器只是供当前内嵌汇编临时使用的情况。比如:
asm("movl %0, %%ebx" : : "a"(foo) : "%ebx");
寄存器%ebx出现在“汇编语句模板”中,并且被movl指令修改,但却未被任何输入或输出操作表达式指定,所以你需要在“破坏描述部分”指定"%ebx",以让GCC知道这一点。
因为你在输入或输出操作表达式所指定的寄存器,或当你为一些输入或输出操作表达式使用"r"、"g"约束,让GCC为你选择一个寄存器时,GCC对这些寄存器是非常清楚的——它知道这些寄存器是被修改的,你根本不需要在“破坏描述部分”再声明它们。但除此之外,GCC对剩下的寄存器中哪些会被当前的内嵌汇编修改一无所知。所以如果你真的在当前内嵌汇编语句中修改了它们,那么就最好“破坏描述部分”中声明它们,让GCC针对这些寄存器做相应的处理。否则有可能会造成寄存器的不一致,从而造成程序执行错误。
在“破坏描述部分”中指定这些寄存器的方法很简单,你只需要将寄存器的名字使用双引号引起来。如果有多个寄存器需要声明,你需要在任意两个声明之间用逗号隔开。比如:
__asm__("movl %0, %%ebx; popl %%ecx" : : "a"(foo) : "%ebx", "%ecx" );
eg:
- 注意:
asm("mov %%eax, %%ebx" :)和__asm__("mov %eax, %ebx") 正确
asm("mov %eax, %ebx" :)和__asm__("mov %%eax, %%ebx")不正确
gcc编译的代码Windows可能运行有问题
mykernel实验和三个法宝
- 存储程序计算机:
冯诺依曼体系 - 中断:
多道程序设计,CPU将当前eip\esp\ebp压到内核堆栈的另外一个堆栈里面去,把eip指向中断处理程序入口,保存现场,执行流的切换。CPU和内核代码共同实现了保存现场和恢复现场,周期性时钟中断 - 堆栈:
c语言程序运行必须的记录路径参数的空间,可以函数调用框架、传递参数、提供局部变量空间、保存返回地址等等
函数调用堆栈
- 建立函数调用框架
push %ebp
movl %esp,%ebp#调用者建立被调用者函数的堆栈框架
//函数体//
movl %ebp,%esp
popl %ebp
ret#拆除被调用者函数的堆栈框架
实验楼mykernel实验指导(操作系统是如何工作的)
cd LinuxKernel/linux-3.9.4
rm -rf mykernel
patch -p1 < ../mykernel_for_linux3.9.4sc.patch
make allnoconfig
make#当出现shiyanlou:~/ $才算编译完成
qemu -kernel arch/x86/boot/bzImage
执行代码效果图:
2018-10-25
- 立即寻址修改了寄存器的值为什么说没有和内存打交道?
和同学讨论后认为寄存器在CPU里所以寄存器的值可能不在内存中。因此直接给寄存器赋值不和内存打交道。
2018-10-26
- 这个问题是四天前的问题,寄存器里存的到底是数值还是地址?
今天看《庖丁解牛》发现EBX存的值是一个内存地址,也是一个数值。也就是说寄存器存的数值可以等于地址,寄存器存数值。
但是这样一来,我觉得寄存器寻址和间接寻址一样了。按说应该有区别,区别是什么呢?。。。 - esp指向的位置是不是就是esp存储的值作为地址指向的位置?
看书发现是的。寄存器存储的数值减4=寄存器向下移一个单元 - 销毁栈有时是popl %ebp,有时是popl %eip什么时候用哪个?
ret 语句对应popl %eip,leave 语句对应popl %ebp
movl %esp是什么意思? - 进程结构体是什么?
进程是处于执行期的程序以及它所管理的资源(如打开的文件、挂起的信号、进程状态、地址空间等等)的总称。注意,程序并不是进程,实际上两个或多个进程不仅有可能执行同一程序,而且还有可能共享地址空间等资源。 - asm volatile("movl %1,%%esp\n\t")最后的\n\t是什么意思?
明天学下怎么用百度