我已经编写了自己的setjmp/longjmp,符合我的需求,如下所示.我在32位系统上进行了测试,效果很好.为此目的,我保存并恢复寄存器eax,ebx,ecx,edi,esi,esp,ebp和eip.
但是,我知道,对于64位系统来说,这还不够.首先,我想我需要用rX替换寄存器eX.其次,我想我需要保存x86-64位中的8个额外寄存器,即r8,r9,r10,r11,r12,r13,r14,r15.这还不够,还是我需要做更多?
#define MY_SETJMP(n) __asm__ __volatile__ ("movl %eax, regax"#n";" \
"movl %ebx, regbx"#n";" \
"movl %ecx, regcx"#n";" \
"movl %edi, regdi"#n";" \
"movl %esi, regsi"#n";" \
"movl %esp, regsp"#n";" \
"movl %ebp, regbp"#n";" \
"call next"#n";" \
"next"#n": pop regip"#n";" \
"addl $6, regip"#n";" \
)
#define MY_LONGJMP(n) __asm__ __volatile__ ("movl regax"#n", %eax;" \
"movl regbx"#n", %ebx;" \
"movl regcx"#n", %ecx;" \
"movl regdi"#n", %edi;" \
"movl regsi"#n", %esi;" \
"movl regsp"#n", %esp;" \
"movl regbp"#n", %ebp;" \ …Run Code Online (Sandbox Code Playgroud) 我正在看gcc通过使用-s标志生成的汇编代码。一些语句如下所示。
movl is_leader(%rip), destination
Run Code Online (Sandbox Code Playgroud)
在此,is_leader是C代码中int类型的全局定义变量。我不明白的是这里的术语is_leader(%rip)。不撕裂指令指针吗?我需要知道该语句如何用于访问is_leader。
在某些地方,我已经读过堆栈从较高的地址变为较低的地址,但是当我自己检查它时,我注意到它从较低地址变为较高地址.例如,我为地址为2aba5ab06010的线程分配了堆栈, 并且在某些时候发现它的值为2aba5b7050f0,这显然大于堆栈的顶部.
但是当我检查反汇编时,我可以看到函数序言减去%rsp和epilogues添加它,所以在这个意义上,不应该是%rsp的值小于堆栈的顶部.为什么这些矛盾的结果呢?
请注意,我在x86 64位机器和gcc编译器上使用Linux.
我想创建一个进程乙从过程一.但是,我不希望B成为A的孩子,如果我只使用fork就会出现这种情况.我怎样才能做到这一点?换句话说,即使进程A被杀死,我也希望进程B继续执行.
我想通过一些函数来获取线程的堆栈地址,我们可以通过它传递pthread_self().可能吗?我这样做的原因是因为我想为其堆栈中的某个线程编写我自己分配的线程标识符.我可以写在堆栈的末尾附近(堆栈内存的末尾而不是当前的堆栈地址.我们可以预期应用程序不会到达堆栈的底部,因此从那里使用空间).
换句话说,我想使用线程堆栈在那里放置一种线程局部变量.那么,我们是否有像pthread提供的以下功能?
stack_address = stack_address_for_thread( pthread_self() );
Run Code Online (Sandbox Code Playgroud)
为此,我可以使用gcc的线程局部变量的语法,但我处于无法使用它们的情况.
我有一个具有以下结构的代码.
#pragma omp parallel for
for( i = 0; i < N; i++ )
{
.....
index = get_index(...);
array[index] = ...;
.....
}
Run Code Online (Sandbox Code Playgroud)
现在index每个线程的值都是唯一的(它永远不会为不同的线程重叠),但是当然OpenMP无法猜测这个,我想是使用同步对象来访问array.
我怎么能要求openmp不要使用同步对象,array并依赖我,这个index值对于不同的线程是唯一的.我试图放入array私人列表,但是因此出现了分段错误.
假设我有一个使用共享对象库X的程序,它与我的程序分开编译.现在,当我为X编写代码时,我需要引用一个变量,比如A,它在我的程序中声明(将使用X库).如何在X代码中引用变量A?弱参考?extern关键字?还是其他一些技巧?
对于以下代码
static inline float fix2float(int64_t f)
{
return (float)f / (1 << 60); // <-- error here
}
Run Code Online (Sandbox Code Playgroud)
编译器给了我这些警告.
warning: left shift count >= width of type
warning: division by zero
Run Code Online (Sandbox Code Playgroud)
当64> 60时,为什么编译器会发出这些警告?