home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / books / mc68ktu2 / mc680010.doc < prev   
Text File  |  1985-11-18  |  12KB  |  516 lines

  1. 02200000000801
  2. 1
  3. 2
  4. 9[...............................................................]0
  5. üMC 68000 ASSEMBLY LANGUAGE COURSE PART XÇ by Mark van den Boer
  6.  
  7. Now  all instructions of the 68000 have been explained it's  time 
  8. to  bring  this knowledge into practice.  This last part  of  the 
  9. course  will  deal  with the subject  of  translating  high-level 
  10. constructs to the equivalent assembler constructs. The C program-
  11. ming  language will be used as the high-level language which  has 
  12. to  be translated to assembler.  A note to those of you  who  are 
  13. more familiar with Pascal or BASIC:  litte imagination is needed 
  14. to deduct the similar constructs in Pascal and BASIC.
  15. What now follows is a C-program which containing several commonly 
  16. used data- and control structures.  The examples show you how  to 
  17. translate these structures into assembler.
  18. There  should  also be a file called M68000.DOC on your  üST  NEWSÇ
  19. disk.  This  file contains a quick-reference card containing  all 
  20. instructions  and allowed addressing modes.  This reference  card 
  21. has been made by Trustware,  Inc.  (an unregistered trademark  of 
  22. Victor Langeveld).  I am very grateful to Victor for allowing  me 
  23. to  include  this card,  since it's a rather tedious job  to  put 
  24. together such a card.  One thing's for sure:  this card is one of 
  25. the  better of its kind and it's the most compact reference  card 
  26. for the 68000 I've ever seen.
  27. /*
  28.         A function. (Called a procedure or function in Pascal
  29.         and a subroutine in BASIC)
  30.         Note how parameters are passed in the assembly language
  31.         translation.
  32.         Als pay attention to how local variables are stored.
  33. */
  34. int function (number, pointer)
  35. int     number;
  36. char    *pointer;
  37. {
  38.         register int    i, j;
  39.         char    *c;
  40.  
  41.         i = number - 1;
  42.         c = pointer;
  43.         c = "new Queensryche album: Operation Mindcrime";
  44.         /* Note how a string is stored */
  45.         return i;          /* Note how a value is returned */
  46. }
  47.  
  48.  
  49. .text
  50. function:
  51. * offset of number = 8
  52. * offset of pointer = 10
  53.         LINK    A6,#-4
  54. * save registers
  55.         MOVEM.L D6-D7,-(sp)     * sp = A7
  56. * i in D7
  57. * j in D6
  58. * offset of c = -4
  59. * i = number - 1
  60.         MOVE.W  8(A6),D7
  61.         SUB.W   #1,D7
  62. * c = pointer
  63.         MOVE.L  10(A6),-4(A6)
  64. * c = "new Queensryche album: Operation Mindcrime"
  65. .data
  66.  
  67.  
  68.  
  69.  
  70.  
  71. L2:
  72.         .dc.b 'new Queensryche album: Operation Mindcrime',0
  73.         MOVE.L  #L2,-4(A6)
  74. * D0 is used for resulting values from functions
  75. * return i; D0 is always used for the result of a function
  76.         MOVE.W  D7,D0
  77. * restore registers
  78.         MOVEM.L (sp)+,D6-D7
  79.         UNLK    A6
  80. * }
  81.         RTS
  82.  
  83. * global variables
  84. .bss
  85. * int     i;
  86. i:      .ds.w   1
  87. * char    character
  88. character:      .ds.b   1
  89. * int     *i_pointer
  90. i_pointer:      .ds.l   1
  91.  
  92.  
  93. * int     i_array[10][5]
  94. i_array:        .ds.w   10*5
  95. * one struct is in fact 3 bytes long, but for every structure
  96. * 4 bytes are reserved. This is because the 68000 can only
  97. * address words at even addresses.
  98. * struct { /* this is the equivalent of a record in PASCAL */
  99. *         int     i;
  100. *         char    c;
  101. * } structure[5];
  102. structure:      .ds.b   4*5
  103.  
  104.  
  105. main()
  106. {
  107.         /* assignment of a constant to a variable */
  108.         i = 9;
  109.  
  110.         /* assignment of a constant to a variable */
  111.         character = 'c';
  112.  
  113.         /* assignment of a constant to a variable */
  114.         i_pointer = &i;
  115.         /* watch how indexing of array is done */
  116.         /* integer is 2 bytes, so the address of
  117.            array-element [3][4] is:
  118.            (3 * 5 (the length of i_array[3]) + 4)
  119.            * 2 (size of an integer) = 38.
  120.            So the integer should be stored at i_array + 38.
  121.         */
  122.         i_array[3][4] = *i_pointer;
  123.  
  124.         /* Now the distance in bytes from the beginning of the
  125.            array must be computed during program execution,
  126.            in contrary to the previous example.
  127.         */
  128.         i_array[i][i - 1] = 2;
  129.  
  130.         /* Assignments to arrays of structures */
  131.         structure[1].i = 3;
  132.         structure[i].c = character;
  133.  
  134.         /* expression evaluation and assignment */
  135.         i = i_array[0][0] * i_array[0][1] +
  136.             i_array[0][2] / i_array[0][3];
  137.         /* conditional statement */
  138.         if (i < i_array[i][i]) i = 1;
  139.         else i = 2;
  140.  
  141.         /* while loop */
  142.         while (i <= 10) i++;
  143.         /* continue and break statements */
  144.         while (i++ <= 10) {
  145.                 if (i != 4) continue;
  146.                 else break;
  147.         }
  148.  
  149.         /* for loop */
  150.         for (i = 4; i >= 0; i--) i_array[i][i] = i;
  151.  
  152.         /* do loop */
  153.         do i++; while (i < 10 && i != 5);
  154.  
  155.         /* switch statement; watch the application of a
  156.            jump-table. Pay special attention to how 'case 4'
  157.            which must 'default' is solved.
  158.  
  159.         */
  160.         switch (i) {
  161.         case 0:
  162.                 i = 0;
  163.                 break;
  164.         case 1:
  165.                 i = 5;
  166.                 break;
  167.         case 2:
  168.         case 3:
  169.                 i = 7;
  170.                 break;
  171.         case 5:
  172.                 i = 1;
  173.                 break;
  174.         default:
  175.                 i = 2;
  176.                 break;
  177.         }
  178.  
  179.  
  180.  
  181.         /* switch statement;
  182.            watch how 'case 999' has destroyed the
  183.            jumptable-optimization.
  184.         */
  185.         switch (i) {
  186.         case 0:
  187.                 i = 0;
  188.                 break;
  189.         case 1:
  190.                 i = 5;
  191.                 break;
  192.         case 2:
  193.         case 3:
  194.                 i = 7;
  195.                 break;
  196.         case 5:
  197.                 i = 1;
  198.                 break;
  199.         case 999:
  200.                 /* This case should be tested seperately so
  201.                    the assembler code can be more efficient.
  202.  
  203.                 */
  204.                 i = 100;
  205.                 break;
  206.         default:
  207.                 i = 2;
  208.                 break;
  209.         }
  210.  
  211.         /* manipulating bits */
  212.         i = i & 0x2345;
  213.         i = i | 0x2345;
  214.         i = i ^ 0x2345;
  215.         i = ~i;
  216.         i <<= i;
  217.  
  218.         /* using the result of a function */
  219.         i = function(5, &character);
  220.  
  221. }
  222.  
  223. .text
  224.  
  225. main:
  226. * Reserve 4 bytes. This way, when the first parameter for a
  227. * function is pushed onto the stack, no pre-decrementing of sp
  228. * has to be done. This 'trick' is used by the DRI-C-compiler.
  229.         LINK    A6,#-4
  230. * i = 9
  231.         MOVE.W  #9,i
  232. * character = 'c'
  233.         MOVE.B  #'c,character
  234. * i_pointer = &i
  235.         MOVE.L  #i,i_pointer
  236. * i_array[3][4] = *i_pointer
  237.         MOVE.L  i_pointer,A0
  238.         MOVE.W  (A0),38+i_array
  239. * i_array[i][i - 1] = 2
  240.         MOVE.W  i,D0     * compute byte offset from first element
  241.         MULS    #10,D0
  242.         MOVE.W  i,D1
  243.         SUB.W   #1,D1
  244.         ASL.W   #1,D1   * multiply by 2 because an int is 2 bytes
  245.         EXT.L   D1
  246.         ADD.L   D1,D0
  247.         ADD.L   #i_array,D0
  248.         MOVE.L  D0,A0   * move computed address to address-reg
  249.         MOVE.W  #2,(A0)
  250. * structure[1].i = 3
  251.         MOVE.W  #3,4+structure
  252. * structure[i].c = character
  253.         MOVE.W  i,A0
  254.         ADD.L   A0,A0
  255.         ADD.L   A0,A0
  256. * Two ADD operations are faster than a MUL and a MOVE
  257.         ADD.L   #structure,A0
  258.         MOVE.B  character,2(A0)
  259. * i = i_array[0][0] * i_array[0][1] +
  260. *     i_array[0][2] / i_array[0][3];
  261.         MOVE.W  i_array,D0
  262.         MULS    2+i_array,D0
  263.         MOVE.W  4+i_array,D1
  264.         EXT.L   D1
  265.         DIVS    6+i_array,D1
  266.         ADD.W   D1,D0
  267.         MOVE.W  D0,i
  268. * if (i < i_array[i][i]) i = 1;
  269. * else i = 2;
  270.         MOVE.W  i,D0
  271.         MULS    #10,D0
  272.         MOVE.W  i,D1
  273.         ASL.W   #1,D1
  274.         EXT.L   D1
  275.         ADD.L   D1,D0
  276.         MOVE.L  D0,A0
  277.         MOVE.L  #i_array,A1
  278.         MOVE.W  0(A0,A1.L),D0
  279.         CMP     i,D0
  280.         BLE     L4
  281. * i = 1
  282.         MOVE.W  #1,i
  283.         BRA     L5
  284. L4:
  285. * i = 2
  286.         MOVE.W  #2,i
  287. L5:
  288.         BRA     L8
  289.  
  290.  
  291. * while (i <= 10) i++;
  292. * This loop has been optimized:
  293. * one BRA instruction was saved by putting the test after the
  294. * do-part. The label L5:    BRA L8    takes care that the while
  295. * condition is executed first at the beginning of the loop
  296. L7:
  297.         ADD.W   #1,i
  298. L8:
  299.         CMP.W   #10,i
  300.         BLE     L7
  301. * while (i++ <= 10) {
  302. *   if (i != 4) continue;
  303. *   else break;
  304. * }
  305. L6:
  306.         BRA     L11
  307. L10:
  308.         CMP.W   #4,i
  309.         BNE     L11
  310.         BRA     L9
  311.  
  312.  
  313. L11:
  314.         CMP     #10,i
  315.         MOVE.W  SR,D0   * save condition codes
  316.         ADD.W   #1,i
  317.         MOVE    D0,CCR  * and restore
  318.         BLE     L10
  319. * for (i = 4; i >= 0; i--) i_array[i][i] = i
  320. L9:
  321.         MOVE.W  #4,i
  322.         BRA     L14
  323. L15:
  324.         MOVE.W  i,D0
  325.         MULS    #10,D0
  326.         MOVE.W  i,D1
  327.         ASL.W   #1,D1
  328.         EXT.L   D1
  329.         ADD.L   D1,D0
  330.         ADD.L   #i_array,D0
  331.         MOVE.L  D0,A0
  332.         MOVE.W  i,(A0)
  333. L13:
  334.         SUB.W   #1,i
  335. L14:
  336.         TST     i
  337.         BGE     L15
  338. L12:
  339. * do i++; while (i < 10 && i != 5);
  340. L18:
  341.         ADD.W   #1,i
  342. L17:
  343.         CMP.W   #10,i
  344.         BGE     L10000
  345.         CMP.W   #5,i
  346.         BNE     L18
  347. L10000:
  348. * switch (i) {
  349. * case 0:
  350. *        i = 0;
  351. *        break;
  352. * case 1:
  353. *        i = 5;
  354. *        break;
  355.  
  356.  
  357. * case 2:
  358. * case 3:
  359. *        i = 7;
  360. *        break;
  361. * case 5:
  362. *        i = 1;
  363. *        break;
  364. * default:
  365. *        i = 2;
  366. *        break;
  367. * }
  368. L16:
  369.         MOVE.W  i,D0
  370.         BRA     L20
  371. L21:
  372.         CLR.W   i
  373.         BRA     L19
  374. L22:
  375.         MOVE.W  #5,i
  376.         BRA     L19
  377.  
  378.  
  379. L23:
  380. L24:
  381.         MOVE.W  #7,i
  382.         BRA     L19
  383. L25:
  384.         MOVE.W  #1,i
  385.         BRA     L19
  386. L26:
  387.         MOVE.W  #2,i
  388.         BRA     L19
  389. L20:
  390. * Test if i is in case-range
  391. * if not goto default
  392. * if in range compute address to jump to
  393.         CMP.W   #5,D0
  394.         BHI     L26
  395.         ASL.W   #2,D0
  396.         MOVE.W  D0,A0
  397.         ADD.L   #L27,A0
  398.         MOVE.L  (A0),A0
  399.         JMP     (A0)
  400. .data
  401. L27:
  402. * jumptable
  403. .dc.l L21
  404. .dc.l L22
  405. .dc.l L23
  406. .dc.l L24
  407. .dc.l L26
  408. .dc.l L25
  409. .text
  410. L19:
  411. * switch (i) {
  412. * case 0:
  413. *         i = 0;
  414. *         break;
  415. * case 1:
  416. *         i = 5;
  417. *         break;
  418. * case 2:
  419. * case 3:
  420. *         i = 7;
  421. *         break;
  422.  
  423. * case 5:
  424. *         i = 1;
  425. *         break;
  426. * case 999:
  427. *         /* This case should be tested seperately so
  428. *            the assembler code can be more efficient.
  429. *         */
  430. *         i = 100;
  431. *         break;
  432. * default:
  433. *         i = 2;
  434. *         break;
  435. * }
  436.         MOVE.W  i,D0
  437.         BRA     L29
  438. L30:
  439.         CLR.W   i
  440.         BRA     L28
  441. L31:
  442.         MOVE.W  #5,i
  443.         BRA     L28
  444.  
  445. L32:
  446. L33:
  447.         MOVE.W  #7,i
  448.         BRA     L28
  449. L34:
  450.         MOVE.W  #1,i
  451.         BRA     L28
  452. L35:
  453.         MOVE.W  #100,i
  454.         BRA     L28
  455. L36:
  456.         MOVE.W  #2,i
  457.         BRA     L28
  458.         BRA     L28
  459. L29:
  460.         EXT.L   D0
  461.         MOVE.L  #L37,A0
  462.         MOVE.W  #6,D1
  463.  
  464.  
  465.  
  466.  
  467. L38:
  468.         CMP.L   (A0)+,D0
  469.         DBEQ    D1,L38
  470.         MOVE.L  24(A0),A0
  471.         JMP     (A0)
  472. .data
  473. L37:
  474. * table of case values
  475. .dc.l 0
  476. .dc.l 1
  477. .dc.l 2
  478. .dc.l 3
  479. .dc.l 5
  480. .dc.l 999
  481. .dc.l 0
  482. * jump table
  483. .dc.l L30
  484. .dc.l L31
  485. .dc.l L32
  486. .dc.l L33
  487. .dc.l L34
  488. .dc.l L35
  489. .dc.l L36
  490. .text
  491. L28:
  492. * i = i & 0x2345
  493.         ANDI.W  #$2345,i
  494. * i = i | 0x2345
  495.         ORI.W   #$2345,i
  496. * i = i ^ 0x2345
  497.         EORI.W  #$2345,i
  498. * i = ~i
  499.         NOT.W   i
  500. * i <<= i
  501.         MOVE.W  i,D1
  502.         MOVE.W  D1,D0
  503.         ASL.W   D1,D0
  504.         MOVE.W  D0,i
  505. * i = function (5, &character)
  506.         MOVE.W  #51,(sp)
  507.         MOVE.L  #character,-(sp)
  508.         ADDQ.L  #4,sp
  509.         MOVE.W  D0,i
  510.  
  511. L3:
  512.         UNLK    A6
  513.         RTS
  514.  
  515. I  would like to thank all people who have attended  this  course 
  516. and who have reflected in some way.