OSコースの練習として、単純なユーザーレベルのスレッドライブラリをコーディングしようとしています。最初のステップとして、私はプログラムを実行し、最初のプログラムを残す関数にジャンプしようとしています。コードはこれまでです:Cとアセンブリを持つ単純なスレッドをコードします。
初期プログラム:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#define STACK_SIZE (sizeof(void *) * 512)
void proc2() //This is the function that should run as the thread.
{
int i;
for(i=0;i<30;i++)
{
printf("Here I am!\n");
sleep(0.5);
}
exit(0);
}
void* malloc_stack() //used to malloc the stack for the new thread.
{
void *ptr = malloc(STACK_SIZE + 16);
if (!ptr) return NULL;
ptr = (void *)(((unsigned long)ptr & (-1 << 4)) + 0x10); //size align
return ptr;
}
int main()
{
int *bp, *sp;
sp = malloc_stack();
bp = (int*) ((unsigned long)sp + STACK_SIZE);
proc1(&proc2,sp,bp); //the actual code that runs the thread. Written in assembly
assert(0);
}
そして私は、単純な組立3つの引数を取りPROC1と呼ばれるコード(命令ポインタとして使用)関数へのポインタ、スタックを書きました現在のレジスタをこれらの値に置き換えます。
.globl proc1
proc1:
movq %rdx, %rbp #store the new base pointer
movq %rsi,%rsp #store the new stack pointer
jmp %rdi #jump to the new instruction pointer.
しかし、私はこのコードを実行すると、私が取得することは、セグメンテーションフォールトである:私が書いたコードです。ここでエラーを見つけるのを手伝ってください。
gcc -g test.c switch.s
gdb a.out
run
をしかし、それは./a.outのように一人でRUSときには、それは動作しません!!!!:私は、次のコマンドを使用してGDBの下でそれを実行したとき
は、まあ、それが正常に動作しています 助けてください。
ありがとうございます。 jmp
がmovq %rax,%rsp
を書かれており、%rsp
が明確に要求されるされる前に、あなたのあなたのアセンブリの上部にmovq
は(まあ、あなたの前に編集した:-)「でした」)
movq dst,src
が、あなたのmovq
として書かれている
、あなたはおそらくしたくない "&PROC2" ... Q:あなたのコンパイラ/デバッガは何ですか? GCCとGDB?途中でキー変数を見て、デバッガでコードをステップ実行しようとしましたか?そうでない場合は、どうしてですか? – paulsm4
segfaultが発生した場合、プログラマは通常、segfaultが100%繰り返し可能な場合は、デバッガを起動してsegフォルトが正確に発生した場所を確認します。あなたもそうしなければならないし、おそらく質問を更新してください。 – hyde
@ paulsm4関数のアドレスを取るときには '&'を使うのがいいですし、何が起こっているのかを(おそらく)明確にするので、多くの人がそれを好きです。 – hyde