2011-11-25 6 views
8

두 매크로가 있습니다. 하나는 어셈블리로 쓰여졌고 다른 매크로는 C로 쓰여졌습니다. 두 번째 매크로는 첫 번째 매크로를 사용합니다. 그러나, 나는 또한 휘발성을 가진 어셈블리에서 두 번째 매크로를 작성하여 코드의 배치를 제어 할 수 있습니다. tid은 런타임 값이며 n과 같은 상수가 아닙니다.어떻게이 모든 것을 어셈블리에 작성합니까?

어셈블리에 쓰기 좋은 방법은 무엇입니까? 또한 휘발성 어셈블리와 같은 C 코드의 배치를 제어 할 수 있습니까?

#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; \ 
    } 
+0

tid는 n과 같은 상수가 아니라 런타임 값입니다. – MetallicPriest

+0

(신경 쓰지 마라.) –

+1

'tsp '과'msp '값을 배열에 저장할 수 있습니까? –

답변

6

당신은 어셈블리 코드를 작성하는 방법의 아이디어를 gcc를 요청할 수 있습니다 : gcc -S foo.c 또는 gcc -Wa,-alh=foo.s -c foo.c을. 물론 결과를 향상시킬 수 있습니다. 약간의 추가 작업이 필요합니다 : 어셈블리 덩어리에 전달하는 매개 변수로 %0을 사용하고 clobbered 한 레지스터를 선언하십시오. 익숙하지 않은 경우 Assembler Instructions with C Expression Operands in the GCC manual을 찾으십시오. 이것이 어떻게 보이는지 (경고, 브라우저에 직접 입력 한 것, x86 어셈블리 구문을 실제로 모르는 것).

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

movq 얼마나 많은 바이트를 알아내는 포함하는 것 애호가 방법 - movq-jmp 블록이 걸립니다 (참고 : 내가 확인하지 않은, 내가 8을 사용)하고 그것으로 계산 된 점프를 만드는;

static register int stack_pointer0 asm("msp0"); 

void myfn() { 
    ...... 
    saved_stack_pointer = stack_pointer0; 
    ...... 
} 

OK, 아마하지 않습니다 당신은 GCC를 사용하는 가정

__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") 
1

같은, 당신은 C 변수에 스택 포인터 레지스터를 매핑 할 GNU 확장을 사용을 시도 할 수 있습니다 원래의 코드가 무엇을했는지 (목표가 무엇인지는 분명하지 않았습니다), 나머지 부분을 알아낼 수 있어야합니다.

나는 구문이 올바르다 고 생각하지만, 그렇지 않다면 사과한다. 나는 이것이 일반 레지스터에서 작동한다는 것을 알고 있으며, GCC가 특별한 레지스터를 위해 무엇을해야하는지 잘 알고 있지만 결코 알지 못한다.

희망이 있습니다.

관련 문제