2013-05-17 27 views
2

我想清理我的彙編代碼和povide的方式通過宏調用「NOP」多次:調用C預處理宏多次(通過可變)

#define NOP() asm(" nop") 

#define NOP_N(N) \ 
    NOP(); \ 
    NOP(); \ 
    .... call NOP() N times 

我可以」如果這在宏中是可能的。

顯然,對於性能方面的原因,我不希望這樣的事情:

#define NOP_N(n) { register int i; for(i=0;i<n;i++) asm(" nop"); } 

這違背了NOP的目的:

L17:         ; NOP_N(3); 
     nop 
     addi  1,r0     ; Unsigned 
     cmpi  3,r0 
     blo  L17 

的代碼是C語言和彙編,所以沒有C++可以參與到這裏。此外,編譯器是相當老,不支持可變宏...

+0

如何將它寫爲'N'的宏,'調用NOP()N次',在編碼時必須知道N# –

+1

@Mogria:那麼如果xgbi可以使用C++,那麼這可以相當簡單地完成通過模板元編程,並且不需要任何預處理器技巧。 – jamesdlin

+0

可能的重複:http://stackoverflow.com/q/11532883/946850 – krlmlr

回答

4

我不認爲無界N解決方案是可能的。對於界N你可以做大意如下的內容:

#define REPEAT_0(WHAT) 
#define REPEAT_1(WHAT) WHAT REPEAT_0(WHAT) 
#define REPEAT_2(WHAT) WHAT REPEAT_1(WHAT) 
#define REPEAT_3(WHAT) WHAT REPEAT_2(WHAT) 

#define NOP_N(N) REPEAT_##N(asm("nop");) 

第一部分可以很容易地自動生成。第二部分採用的技術有時稱爲token pasting

+0

這是我可以預見的最接近的,沒有可變宏。 – Gui13

2

怎麼樣thisIs the C preprocessor Turing complete?

#define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__))) 
#define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__))) 
#define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__))) 
#define EVAL3(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__))) 
#define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__))) 
#define EVAL5(...) __VA_ARGS__ 

和REPEAT_INDIRECT

#define REPEAT(count, macro, ...) \ 
    WHEN(count) \ 
    (\ 
     DEFER(REPEAT_INDIRECT)() \ 
     (\ 
      DEC(count), macro, __VA_ARGS__ \ 
     ) \ 
     DEFER(macro) \ 
     (\ 
      DEC(count), __VA_ARGS__ \ 
     ) \ 
    ) 
#define REPEAT_INDIRECT() REPEAT 

//An example of using this macro 
#define M(s, i, _) i 
EVAL(REPEAT(8, M, ~)) // 0 1 2 3 4 5 6 7 

永遠:

#define FOREVER() \ 
    ? \ 
    DEFER(FOREVER_INDIRECT)()() 
#define FOREVER_INDIRECT() FOREVER 
// Outputs question marks forever 
EVAL(FOREVER()) 
+1

請注意詳細說明此代碼的作用?否則,評論中的鏈接很好,但不符合答案。 – krlmlr

0

如果重新盟主希望在預處理器中執行此操作(並且具有符合C99的編譯器),則可以使用P99中的P99_UNROLL

但是,你完全低估了現代編譯器的優化能力。只要邊界是編譯時間常量,一個優化的編譯器應該爲你展開代碼。看看彙編器確定(gcc有-S)。

但你可能可以通過編碼這種「正確」有點幫助編譯器:

也就是說,具有循環計數器本地的for並使用一個無符號的類型,使得不能溢出的理論問題。

+0

問題是編譯器*是*舊的。我檢查了使用for循環將實際初始化整數並且不展開循環。 – Gui13