用C和汇编编写一个简单的线程

use*_*802 9 c assembly x86-64

我正在尝试编写一个简单的用户级线程库作为我的OS课程的练习.作为第一步,我试图运行一个程序并跳转到一个函数离开第一个程序.到目前为止的代码是这样的:

最初的计划:

#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);
}
Run Code Online (Sandbox Code Playgroud)

然后我编写了一个名为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.
Run Code Online (Sandbox Code Playgroud)

但是当我运行这段代码时,我得到的是一个分段错误.请帮我在这里找到错误.

当我使用以下命令在GDB下运行它时,它正常工作:

gcc -g test.c switch.s
gdb a.out
run
Run Code Online (Sandbox Code Playgroud)

但当它像./a.out一样单独使用时,它不起作用!!!! 请帮忙.

提前致谢.

tor*_*rek 2

movq在程序集的顶部(好吧,在编辑之前是“是”:-))写为

movq dst,src
Run Code Online (Sandbox Code Playgroud)

但你movq之前jmp写的movq %rax,%rsp%rsp显然是所需的 dst。这显然是错误的,不知道还有什么。