Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write all of this in assembly

I have two macros, one is written in assembly and the other in C. The second macro uses the first macro. However, I also want to write the second macro in assembly with volatile, so I can control its placement in the code. And please note that tid is a runtime value, not a constant like n.

What is a good way to write that in assembly? Also, is it possible to control placement of a C code like assembly with volatile?

#define SAVE_SP(n) __asm__ __volatile__ ("movq %rsp, msp"#n";" \
     "movq ts"#n", %rsp;" \
     )

#define SAVE_STACK_POINTER( tid ) \
    switch( tid ) \
    { \
        case 0: \
            SAVE_SP( 0 ); \
            break; \
        case 1: \
            SAVE_SP( 1 ); \
            break; \
        case 2: \
            SAVE_SP( 2 ); \
            break; \
        case 3: \
            SAVE_SP( 3 ); \
            break; \
    }
like image 751
MetallicPriest Avatar asked Nov 25 '11 16:11

MetallicPriest


People also ask

How do you comment out multiple lines in assembly?

In assembly, comments are usually denoted by a semicolon ; , although GAS uses # for single line comments and /* … */ for block comments possibly spanning multiple lines.

What is RESB in assembly language?

RESB , RESW , RESD , RESQ and REST are designed to be used in the BSS section of a module: they declare uninitialised storage space. Each takes a single operand, which is the number of bytes, words, doublewords or whatever to reserve.

What is assembly example?

The definition of an assembly is a grouping of people together typically for a specific reason. An example of an assembly is a musical performance by the orchestra at an elementary school.


1 Answers

You can ask gcc its idea of how to write your code in assembly: gcc -S foo.c or gcc -Wa,-alh=foo.s -c foo.c. You may want to improve on the results, of course. You will need to do a little extra: use %0 for the parameter that you pass for the assembly chunk, and declare the registers that you've clobbered. Look up Assembler Instructions with C Expression Operands in the GCC manual if you aren't familiar. Here's how this might look like (warning, typed directly into the browser, and don't really know x86 assembly syntax).

#define SAVE_STACK_POINTER(tid) __asm__ __volatile__ (" \
        cmpl $0, %0                                   \n\
        je .SAVE_STACK_POINTER_0                      \n\
        cmpl $1, %0                                   \n\
        je .SAVE_STACK_POINTER_1                      \n\
        cmpl $2, %0                                   \n\
        je .SAVE_STACK_POINTER_2                      \n\
        cmpl $3, %0                                   \n\
        je .SAVE_STACK_POINTER_3                      \n\
        jmp .SAVE_STACK_POINTER_done                  \n\
      .SAVE_STACK_POINTER_0:                          \n\
        movq %%rsp, msp0                              \n\
        movq ts0, %%rsp                               \n\
        jmp SAVE_STACK_POINTER_done                   \n\
      .SAVE_STACK_POINTER_1:                          \n\
        movq %%rsp, msp1                              \n\
        movq ts1, %%rsp                               \n\
        jmp SAVE_STACK_POINTER_done                   \n\
      .SAVE_STACK_POINTER_2:                          \n\
        movq %%rsp, msp2                              \n\
        movq ts2, %%rsp                               \n\
        jmp SAVE_STACK_POINTER_done                   \n\
      .SAVE_STACK_POINTER_3:                          \n\
        movq %%rsp, msp3                              \n\
        movq ts3, %%rsp                               \n\
      .SAVE_STACK_POINTER_done:                       \n\
    " : : "r" (tid))

A fancier method would involve figuring out how many bytes each movq-movq-jmp block takes (note: I haven't checked, I use 8) and making a computed jump into it; something like

__asm__("                        \n\
    movl %0, %eax                \n\
    mul  8, %eax                 \n\
    add  4, %eax                 \n\
    jmp . + %eax                 \n\
    movq %%rsp, msp0             \n\
    movq ts0, %%rsp              \n\
    jmp .SAVE_STACK_POINTER_done \n\
    …
  .SAVE_STACK_POINTER_done:      \n\
" : : "r" (tid) : "%eax")
like image 103
Gilles 'SO- stop being evil' Avatar answered Oct 04 '22 23:10

Gilles 'SO- stop being evil'