Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code a simple thread with C and assembly

Tags:

c

assembly

x86-64

I'm trying to code a simple user-level thread library as an exercise for my OS course. As the first step, I am trying to run a program and jump to a function leaving the first program. The code so far is this:

The initial program:

#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);
}

And then I wrote a simple assembly code called proc1 that takes three arguments, pointer to a function (used as the instruction pointer), stack pointer and base pointer and replace the current registers with these values. The code I wrote is:

.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.

But when I run this code, what I get is a segmentation fault. Please help me to find the error here.

Well it's working correctly when I ran it under GDB using the following commands:

gcc -g test.c switch.s
gdb a.out
run

but when it rus alone as in ./a.out, it doesn't work!!!! Please help.

Thanks in advance.

like image 640
user2290802 Avatar asked Apr 21 '13 07:04

user2290802


People also ask

Is C good for multithreading?

C does not contain any built-in support for multithreaded applications. Instead, it relies entirely upon the operating system to provide this feature. This tutorial assumes that you are working on Linux OS and we are going to write multi-threaded C program using POSIX.

What is main thread in C?

In the main thread (i.e. main function; every program has one main thread, in C/C++ this main thread is created automatically by the operating system once the control passes to the main method/function via the kernel) we are calling pthread_cond_signal(&cond1); .


2 Answers

Try changing your code to include the assembly instructions directly in the C source as follow:

void proc1(void (*fun)(), int *sp, int *bp){
    register int *sptr asm ("%rsi") = sp;
    register int *bptr asm ("%rdx") = bp;
    register void (*fptr)() asm ("%rdi") = fun;

    asm (
        "mov %rdx, %ebp\n"
        "mov %rsi, %esp\n"
        "jmp *%rdi\n"
    );
}

The above code ensures that the parameters to proc1 are in the right registers (although your code seems to be correct wrt the abi). Note the * in front of the jmp argument, which my version of gnu as warned about when I first tried your code.

With the above function, and code compiled with -g you should be able to debug it properly (use the breakpoint instruction on proc1 and info registers to check the content of the cpu).


The issue is actually on the %rsp pointer, which must always be equal to or greater than %rbp (the stack grows downward). Simply passing bp instead of sp to proc1 in main should fix the issue:

 proc1(&proc2, bp, bp);

2 small remarks:

  • don't forget to give proc1 prototype in the C code for the asm version:

    extern void proc1(void (*)(), int *, int *);
    
  • the sleep libc function only take unsigned long, not float.

    sleep(1);
    
like image 59
didierc Avatar answered Sep 17 '22 16:09

didierc


Your movq at the top of your assembly are (well, "were" before you edited :-) ) written as

movq dst,src

but your movq before the jmp is written movq %rax,%rsp and %rsp is clearly the desired dst. That's obviously wrong, not sure about anything else.

like image 29
torek Avatar answered Sep 17 '22 16:09

torek