How to write it all in the assembly

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

What is a good way to write this in an assembly? Also, is it possible to control the placement of C code, such as assemblies with mutable?

#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; \ } 
+8
c assembly gcc x86 linux
source share
2 answers

You can ask gcc how to write code in the assembly: gcc -S foo.c or gcc -Wa,-alh=foo.s -c foo.c Of course, you can improve the results. You will need to do a little more: use %0 for the parameter that you pass for the assembly, and declare the registers that you bound. See the C Expression Operand Assembler Instructions in the GCC Guide if you are not familiar. Here's what it might look like (a warning entered directly in the browser and don't know the 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)) 

The fancier method will include determining the number of bytes of each block movq - movq - jmp (note: I did not check, I use 8) and taking a calculated 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") 
+6
source share

Assuming you are using GCC, you could try using the GNU extension to map the stack pointer case to variable C:

 static register int stack_pointer0 asm("msp0"); void myfn () { ...... saved_stack_pointer = stack_pointer0; ...... } 

Well, that probably doesn't do what your source code did (I didn't understand what the goal was), but you should be able to figure out the rest from that.

I think I got the syntax correctly, but apologies if not. I know this works for general registers, and I'm sure GCC knows what to do for special registers, but you never know.

Hope this helps.

+1
source share

All Articles