[原]全局寄存器变量

你可以定义全局寄存器变量在gnuc中:
register int *foo asm("a5");
这里a5是被使用的寄存器名字. 选择一个寄存器可以在函数调用中被正常的存取在你机器上, 这样库例程就不会冲刷它.
寄存器名字是跟cpu有关的, 所以你可能需要为你的程序条件化cpu类型. 寄存器a5将会是一个好的选择在68000机器上作为指针型变量.在有寄存器窗口的机器上, 你应该确定去选择一个全局寄存器, 不会被函数调用机制神奇地改变.
另外, 一种类型cpu上的操作系统可能在寄存器命名上不同; 因此你需要额外的条件. 例如, 一些68000操作系统称寄存器为%a5.
最后, 可能存在一种方式要求编译器去自动地选择一个寄存器, 但是首先我们需要指出应该如何选择, 以及如何允许你去指导选择. 没有明显的解决方案.
定义一个全局寄存器变量, 在一个特定的寄存器保留所有的寄存器对于这些应用, 至少在当前编译的范围中.
寄存器不会为在当前的编译中, 当前函数中, 为其他任何目的分配寄存器.寄存器不会被这些函数保护和恢复. 存储在这些寄存器中从来不会被删除, 即使他们变为不活跃的, 但是引用可能会被删除, 移动, 或者简化.

如果这是不安全的去访问全局寄存器变量, 从信号处理中, 或者从多个线程的控制中, 因为系统库例程可能会临时使用这些寄存器为其他目的(除非你重编译他们为当前的任务).

使用全局寄存器的函数是不安全的, 去调用另一个这样的函数. 这是因为lose可能会保存寄存器并且放另外一些值到那里.例如, 你不会希望一个全局寄存器变量在比较函数中可用, 当你通过qsort, 因为qsort可能放其他一些东西到寄存器中.

如果你希望重编译qsort, 或者其他源文件没有使用你的全局寄存器变量, 因此他们就不会使用那个寄存器用于其他目的, 就可以满足特定的编译选项-ffixed-REG. 你不需要添加全局寄存器变量声明在他们的源代码中.

一个函数可以改变全局寄存器变量中的值, 不能被其他没有该变量的函数安全的调用, 因为他可能冲刷调用这期望从中找到的返回值. 因此, 作为程序入口点的函数使用全局寄存器变量必须显式的保存和恢复调用者的值.

在许多机器上, 长跳转将会恢复每一个全局寄存器变量的值, 值要在setjmp时设置. 在一些机器上, 然而, longjmp不会改变全局寄存器变量的值. 为了可移植性, setjmp函数应该做一些其他安排用来保存全局寄存器变量的值, 并为恢复他们在longjmp中. 通过这种方式, 同样的事将会发生, 而不论longjmp做什么.

所有的全局寄存器变量, 必须在函数定义之前声明. 如果这种声明可以放在函数定义之后, 声明可能太晚了用来阻止寄存器被其他目的所使用, 在之前的函数中.

全局寄存器变量可能没有初值, 因为一个可执行文件没有方法支持寄存器初值.





作者:liyonghelpme 发表于2010/6/10 13:07:00 原文链接
阅读:403 评论:0 查看评论
原文地址:https://www.cnblogs.com/liyonghelpme/p/4273558.html