1 / 46

系統程式

系統程式. Chapter 4 : Macro Processors. Expanded Assembly Programs. Core Assemblers. Object Programs. Linkers. Libraries. Loaders. Executables. Assembling Programs for Execution. Assembly Programs. Macro Processors. # define ABSDIFF(X,Y) ((X) > (Y) ? (X)-(Y):(Y)-(X))

khuong
Download Presentation

系統程式

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 系統程式 Chapter 4: Macro Processors

  2. Expanded Assembly Programs Core Assemblers Object Programs Linkers Libraries Loaders Executables Assembling Programs for Execution Assembly Programs Macro Processors

  3. #define ABSDIFF(X,Y) ((X) > (Y) ? (X)-(Y):(Y)-(X)) #define WRONG(X,Y) X > Y ? X - Y : Y - X int main() { int i, j, k; k = ABSDIFF(i,j); k = ABSDIFF(i-j, j-x); k = WRONG(i-j, j-x); return 0; } int main() { int i, j, k; k = (( i ) > ( j ) ? ( i )-( j ):( j )-( i )) ; k = ((i-j) > (j-x) ? (i-j)-(j-x):( j-x )-(i-j)) ; k = i-j > j-x ? i-j - j-x : j-x - i-j ; return 0; } An Example in C gcc –E –P abc.c

  4. Macro Definition and Expansion • Macro definition (Fig. 4.1) • parameters • prototype • body • Macro expansion ( Fig. 4.2) • invocation (macro call) • arguments • Relative addressing and labels in macro prototypes

  5. Figure 4.1 macro definition macro invocation

  6. parameters prototype body A Simple SIC/XE Macro Definition

  7. Figure 4.2

  8. Labels in Macro Definitions

  9. Figures 2.6 and 4.2 Figure 2.6

  10. Figure 4.2

  11. Macro Processors • A simple two-pass macro processors • How • Record macro definitions in the first pass. • Process macro invocations in the second pass.

  12. One-Pass Macro Processors • Macro definitions must precede macro invocations. • Data structures • DEFTAB • no comment lines • parameters converted to positional notation (?n) • NAMTAB • ARGTAB

  13. Figure 4.4

  14. Nested Macro Definitions • Examples (Fig. 4.3) • Why? • Problems • Notice that we are NOT talking about macro invocations in macro definitions (Sec. 4.3.1)

  15. Figure 4.3

  16. LEVEL = 2 LEVEL = 2 LEVEL = 1 Nested Macro Definitions MACROS MACRO RDBUFF MACRO &INDEV,&BUFADR,&RECLTH …… MEND WRBUFF MACRO &OUTDEV,&BUFADR,&RECLTH …… MEND …… …… MEND What if this macro is invoked twice? Recursive macro expansion…(Sec. 4.3.1)

  17. Figure 4.5 LEVEL=0 LEVEL=2 LEVEL=1 LEVEL=1 MACROS MACRO INSIDE MACRO &A LDA &A MEND MEND

  18. Features • Concatenating macro parameters • What (page 186) • Marking the start and end of the parameters • Examples (Figure 4.6) • Unique labels • Use special methods to indicate local variables • $[0-9A-Z]{2}original-label in SIC • LOCAL command in MASM

  19. Concatenating Macro Parameters SUM MACRO &ID LDA X&ID1 ADD X&ID2 ADD X&ID3 STA X&IDS MEND SUM MACRO &ID,&ID1 LDA X&ID1 ADD X&ID2 ADD X&ID3 STA X&IDS ……… LDT &ID1 MEND SUM X,Y

  20. Labels in Macro Definitions SAM START 0 HERE MACRO &PARAM1 AGAIN LDA #&PARAM1 MEND HIHI LDX #0 HERE 4 HERE 5 END HIHI WHAT IF WE DO NEED TO USE LABELS? SAM START 0 HIHI LDX #0 AGAIN LDA #4 AGAIN LDA #5 END HIHI This is why we did not use labels in Figure 4.1.

  21. Features (2) • Conditional Macro Expansion • Examples (Fig. 4.8) • Macro processor directive (SET) • Macro-time variables (set symbols) • &xyz • initialized to 0 • How • simple IF-ELSE-ENDIF (trace Fig. 4.8) • simple WHILE-ENDW (trace Fig. 4.9)

  22. IF-ELSE-ENDIF (Fig. 4.8)

  23. WHILE-ENDW (Fig. 4.9)

  24. Features (3) • Keyword Macro Expansion • positional parameters vs. keyword parameters • Examples (pages 197-199) • Why? • Default values • Overriding default values

  25. Design Options • Recursive macro expansion • Examples • Problems • Solving the problems

  26. Design Options (2) • General-purpose macro processors • Advantages vs. disadvantages • Differences in programming languages • comments • statement blocks: begin-end vs. {} • tokens: assignment in C(=) and Pascal (:=) • difficulty in using consistent syntax for macro invocation

  27. Implementation Examples • MASM Macro Processor An integrated macro processor with the assembler • Concatenation operator & • Unique Label ??n

  28. ABSDIF MACRO OP1,OP2,SIZE LOCAL EXIT IFNB <SIZE> IFDIF <SIZE>,<E> ;ERROR .ERR EXITM ENDIF ENDIF MOV SIZE&AX,OP1 SUB SIZE&AX,OP2 JNS EXIT NEG SIZE&AX EXIT: ENDM • ABSDIF J,K • MOV AX,J • SUB AX,K • JNS ??0000 • NEG AX • ??0000: • ABSDIF M,N,E • MOV EAX,M • SUB EAX,N • JNS ??0001 • NEG EAX • ??0001:

  29. ANSI C Preprocessor • #define NULL 0 • #define EOF (-1) • #define EQ == • while ( I EQ 0 ) • -> while ( I == 0 ) • A macro contain a token that happens to match its name.

  30. Avoid multi-include • #ifndef COMDEF_H #define COMDEF_H //context of the header#endif 

  31. “Macro is more efficient” • Avoid the cost of function call

  32. #define ABSDIFF(X,Y) ((X) > (Y) ? (X)-(Y):(Y)-(X)) #define WRONG(X,Y) X > Y ? X - Y : Y - X int main() { int i, j, k; k = ABSDIFF(i,j); k = ABSDIFF(i-j, j-x); k = WRONG(i-j, j-x); return 0; } int main() { int i, j, k; k = (( i ) > ( j ) ? ( i )-( j ):( j )-( i )) ; k = ((i-j) > (j-x) ? (i-j)-(j-x):( j-x )-(i-j)) ; k = i-j > j-x ? i-j - j-x : j-x - i-j ; return 0; } An Example in C gcc –E –P abc.c

  33. “Stringizing” operator # #define DISPLAY(EXPR) printf(“EXPR = %d\n”, EXPR); DISPLAY(I*J+1) printf(“EXPR = %d\n”, I*J+1); #define DISPLAY(EXPR) printf(#EXPR “= %d\n”, EXPR); DISPLAY(I*J+1) printf(“I*J+1” “= %d\n”, I*J+1);

  34. #define DISPLAY(EXPR) printf(#EXPR “= %d\n”, EXPR); DISPLAY(ABSDIFF(3,8)) printf(“ABSDIFF(3,8)” “= %d\n”, ABSDIFF(3,8)); printf(“ABSDIFF(3,8)” “= %d\n”, ( (3) >(8) ? (3) – (8) : (8) – (3) ) ); debug message #define ERR(fmt, ...) fprintf(stderr, "ERR: " fmt "\n\n", ##__VA_ARGS__)

  35. Conditional compilation #ifndef BUFFER_SIZE #define BUFFER_SIZE 1024 #endif #ifdefine DEBUG 1 . #if DEBUG == 1 printf(…) /* debugging output */ #endif #define DEBUG 0 #ifdef DEBUG printf(…) #endif

  36. Use const to replace #define #define ASPECT_RATION 1.653 Const double ASPECT_RATION 1.653; Class GamePlayer { private: static const int NUM_TURNS = 5; int score[NUM_TURNS]; } const int GamePlayer::NUM_TURNS; Effective C++ Meyers

  37. Use inline to replace #define #define max(a, b) ( (a) > (b) ? (a) : (b) ) Int a=5, b=0; max(++a, b); max(a--, b+10); Int a=5, b=0; (++a) > (b) ? (++a) : (b) ; (a--) > (b+10) ? (a--) : (b+10);

  38. Use inline to replace #define #define max(a, b) ( (a) > (b) ? (a) : (b) ) inline const int max(int a, int b) { return a > b ? a : b; } template <class T> inline const T& max(const T& a, const T& b) { return a > b ? a : b; }

  39. template<int N> struct fib { static const int result = fib<N-1>::result + fib<N-2>::result; }; template<> struct fib<2> { static const int result = 1; }; template<> struct fib<1> { static const int result = 1; }; /* function */ cout<<fib<5>::result<<endl;

  40. Unit test /* target code */ int myadd(const int a, const int b) { return a + b; }

  41. Unit test – test case void test_case1(void) { int result = myadd(1, 2); CHECK(result == 3); } void test_case2(void) { int result = myadd(1, -2); CHECK(result == -1); }

  42. Unit test – ut.h int __check_count = 0; int __failure_count = 0; typedef struct { char *desc; void (*func)(void); int failure; int check; } test_suite_t; #define CHECK(expr) \ { ++__check_count; if(! (expr)) { ++__failure_count; \ printf("*check* FAIL!!: %s:%d: %s\n", __func__, __LINE__, # expr); \ }} void test_case1(void) { int result = myadd(1, 2); CHECK(result == 3); }

  43. Unit test – ut.h - run_test_suite() void run_test_suite(test_suite_t *psuite) { int num = 0; int total_failure = 0; int total_check = 0; test_suite_t *iter = psuite; for(;iter->func;++iter) { fprintf(stderr, "\n*Test: %s\n\n", iter->desc); __check_count = 0; __failure_count = 0; iter->func(); iter->failure = __failure_count; iter->check = __check_count; total_failure += __failure_count; total_check += __check_count; }

  44. Unit test – ut.h - run_test_suite() /* report */ fprintf(stderr, "\nTest Report\n\n"); fprintf(stderr, "%4s | %-40s | %s\n", "case", "description", "fail / check"); fprintf(stderr, "-----+------------------------------------------+----------------\n"); for(iter = psuite, num = 1;iter->func;++iter, ++num) { fprintf(stderr, "%4d | %-40s | %4d / %d%s\n", num, iter->desc, iter->failure, iter->check, iter->failure?" FAIL!!":""); } fprintf(stderr, " +==========================================+================\n"); fprintf(stderr, " | final result | %4d / %d\n\n", total_failure, total_check); }

  45. Unit test int main() { test_suite_t suite[] = { {"basic test", test_case1}, {"basic test 2", test_case2}, {NULL, NULL} }; run_test_suite(suite); return 0; }

More Related