CPU0 的組合語言 - 範例集

# 進行資料移動

``````;檔案：cpu0_mov.asm0     -- 用途：進行資料移動
MOV     R1, R2              ;         R1 = R2                  ;```
```

# 指定運算

``````;檔案：cpu0_assign.asm0  -- 用途：記憶體搬移 (指定運算)
LD      R1, B               ;         R1 = B                   ;     A = B
ST      R1, A               ;         A  = R1                  ;```
```

# 數學運算式

``````;檔案：cpu0_exp.asm0      -- 用途：數學運算式
LD      R2, B               ;         R2 = B                   ;     A = B + C - D
LD      R3, C               ;         R3 = C                   ;
LD      R4, D               ;         R4 = D                   ;
ADD     R1, R2, R3          ;         R1 = R2 + R3             ;
SUB     R1, R1, R4          ;         R1 = R1 - R4             ;
ST      R1, A               ;         A  = R1                  ;```
```

# 模擬 if 判斷

``````;檔案：cpu0_if.asm0       -- 用途：模擬 if 判斷

LD  R1, A                   ;         R1 = A;                  ;
LD  R2, B                   ;                                  ;
CMP R1, R2                  ;                                  ;
JGT LABEL1                  ;         R2 = B;                  ;
ST  R2, C                   ;         if (R1 > R2)             ;   if (A>B)
JMP LABEL2                  ;            goto LABEL1;          ;
LABEL1: ST  R1, C                   ;         C = R2;                  ;     C = A;
LABEL2:                             ;         goto LABEL2              ;   else
; LABEL1:                          ;
;         C = R1                   ;     C = B;
; LABEL2:                          ;```
```

# 模擬 while 迴圈

``````;檔案：cpu0_while.asm0      -- 用途：模擬 while 迴圈

LOOP:                               ;     while (1) {
ADD R1, R2, R1                ;       R1 = R1 + R2;
JMP LOOP                      ;     }```
```

# 模擬 for 迴圈

``````;檔案：cpu0_for.asm0         -- 用途：模擬 for 迴圈

START                              ; void main() {                     ;   void main() {
LD      R1, sum            ;      R1 = sum;                    ;     int sum=0;
LD      R2, i              ;      R2 = i;                      ;     int i;
LD      R3, ten            ;      R3 = ten;                    ;     for (i=0; i<=10; i++)
LD      R4, one            ;      R4 = one;                    ;       sum += i;
FOR:    CMP     R2, R3             ;      if (R2 > R3)//(i > 10)       ;   }
JGT     EXIT               ;         goto EXIT;                ;
ADD     R1, R2, R1         ;      R1 = R2 + R1;                ;
ADD     R2, R4, R2         ;      R2 = R2 + R4;                ;
JMP     FOR                ;      goto FOR;                    ;
EXIT:   RET                        ; EXIT:return;                      ;
i       RESW    1                  ;      int i;                       ;
sum     WORD    0                  ;      int sum = 0;                 ;
ten     WORD    10                 ;      int ten = 10;                ;
one     WORD    1                  ;      int one = 1;                 ;
END                                ; }                                 ;```
```

# 使用指標的方式進行字串複製

``````; 檔案：cpu0_strcpy_ptr.asm0   -- 用途：使用指標的方式進行字串複製

START                              ; void main() {                        ; void main() {
LD      R1, i              ;      R1=i;                           ;     char a[10];
LD      R2, aptr           ;      R2=*aptr;                       ;     char b[] = "Hello !";
LD      R3, bptr           ;      R3=*bptr;                       ;     int i = 0;
LD      R7, one            ;      R7=one;                         ;
while:                             ; while:                               ;     while (1) {
ADD     R5, R3, R1         ;      R5 = R3+R1;// R5=&b[i]          ;         a[i] = b[i];
LDB     R4, [R5]           ;      R4 = [R5]; // R4 = b[i]         ;
ADD     R6, R2, R1         ;      R6 = R2+R1;// R6=&a[i]          ;         if (b[i] == '\0')
STB     R4, [R6]           ;      [R6] = R4; // a[i] = R4         ;           break;
CMP     R4, R0             ;      if (R4!= R0)  // b[i] != '\0'   ;         i++;
JEQ     endw               ;        goto endw;                    ;     }
ADD     R1, R1, R7         ;      R1 = R1 + R7; // i++;           ;     return;
JMP     while              ;      goto while;                     ; }
endw:   RET                        ;      endw: return;                   ;
a       RESB    10                 ;      char a[10];                     ;
b       BYTE    "Hello !",0        ;      char b[] = "Hello !"            ;
aptr    WORD    &a                 ;      int *aptr=a;                    ;
bptr    WORD    &b                 ;      int *bptr=b;                    ;
i       WORD    0                  ;      int i=0;                        ;
one     WORD    1                  ;      int one = 1;                    ;
END                                ; }                                    ;```
```

# 使用索引的方式進行字串複製

``````; 檔案：cpu0_strcpy_idx.asm0    -- 用途：使用索引的方式進行字串複製

START                              ;  void main() {                       ;   void main() {
LD      R2, aptr           ;          R2 = *aptr;                 ;      int a[100];
LD      R3, bptr           ;          R3 = *bptr;                 ;      int b[100];
LDI     R8, 1              ;          R8 = 1;                     ;      int *aptr=a;
LDI     R9, 100            ;          R8 = 100;                   ;      int *bptr=b;
ST      R0, i              ;          i = 0;                      ;      int i;
LD      R1, i              ;          R1 = i;                     ;      int a[100], b[100];
FOR:                               ;  FOR:                                ;
SHL     R5, R1, 2          ;          R5 = R1 << 2; // R5=i*4;    ;      for (i=0; i<=100; i++) {
ADD     R6, R5, R2         ;          R6 = R5 + R2; // R6=&a[i]   ;        a[i] = b[i];
ADD R7, R5, R3             ;          R7 = R5 + R3; // R7=&b[i]   ;      }
LD      R5, [R6]           ;          R5 = [R6]; // R5 = a[i]     ;   }
ST      R5, [R7]           ;          [R7] = R5; // b[i] = R5;    ;
ADD R1, R1, R8             ;          R1 = R1+1; // i++;          ;
CMP R1, R9                 ;          If (R1 < R9) // i<=100      ;
JLE     FOR                ;            goto FOR;                 ;
RET                        ;          return                      ;
a       RESW    100                ;  }                                   ;
b       RESW    100                ;                                      ;
aptr    WORD    &a                 ;                                      ;
bptr    WORD    &b                 ;                                      ;
i       RESW    1                  ;                                      ;
END                                ;                                      ;```
```

# 模擬 C 語言的結構存取

``````; 檔案：cpu0_struct.asm0       -- 用途：模擬 C 語言的結構存取

START                              ;  void main() {                       ;  typedef struct {
…                                 ;      …                              ;    char name[20];
LDI     R5, 20             ;      R5 = 20;                        ;    int age;
LD      R1, pptr           ;      R1 = *pptr;                     ;  } person;
ADD     R2, R1, R5         ;      R2 = R1 + R5;// p + 20;         ;
LD      R6, 18             ;      R6 = 18;                        ;  void main() {
ST      R6, [R2]           ;      [R2] = R6; // [p+20] = 18;      ;    person p;
…                                 ;      …                              ;    …
p       RESB    24                 ;      char p[24];                     ;    p.age = 18;
pptr    WORD    &p                 ;      int *pptr = &p;                 ;    …
END                                ;  }                                   ;  }```
```

# 模擬函數呼叫

``````; 檔案：cpu0_call.asm0         -- 用途：模擬函數呼叫

START                              ; void main() {
LD   R1, x                 ;   int x = 1, y;
JSUB f                     ;   y = f(x);
ST   R2, y                 ; }
RET                        ;
x       WORD 1                     ;
y       RESW 1                     ;
f:                                 ; int f(int a) {
ADD  R2, R1, R1            ;   return a+a;
RET                        ; }
END                                ;```
```

# 模擬雙層函數呼叫

``````; 檔案：cpu0_call2.asm0        -- 用途：模擬雙層函數呼叫

MAIN START                         ;  int main()                            ;  int main() {
LD      R1, x              ;      R1 = x;                           ;    int x = 1;
PUSH    R1                 ;      push R1; //push parameter x       ;    int y;
JSUB    f1                 ;      f1();                             ;    y = f1(x);
POP     R1                 ;      POP R1; // R1 = f1()              ;    return 1;
ST      R1, y              ;      y = R1; // y = f1()               ;  }
RET                        ;      return;                           ;
x       WORD    1                  ;      int x = 1;                        ;
y       RESW    1                  ;      int y;                            ;
;                                        ;
f1:                                ;  int f1() {                            ;  int f1(int t) {
POP     R1                 ;      POP R1; // R1=x;                  ;    int b = f2(&t);
PUSH    LR                 ;      PUSH LR //保留連結暫存器          ;    return b+b;
ST      R1, t              ;      t = R1;                           ;  }
LD      R2, pt             ;      R2 = pt;                          ;
PUSH    R2                 ;      PUSH R2; // push &t               ;
JSUB    f2                 ;      f2();                             ;
POP     R1                 ;      POP R1; // R1= f2()               ;
ST      R1, b              ;      b = R1; // b = f2()               ;
ADD     R2, R1, R1         ;      R2 = R1 + R1;                     ;
POP     LR                 ;      POP LR // //回復連結暫存器        ;
PUSH    R2                 ;      PUSH R2; // push b+b              ;
RET                        ;      return; // return b+b;            ;
t       RESW    1                  ;      int t;                            ;
b       RESW    1                  ;      int b;                            ;
pt      WORD    &t                 ;      int *pt = &t;                     ;
;  }                                     ;
f2:                                ;  int f2() {                            ;  int f2(int *p) {
POP     R1                 ;      POP R1; // R1=p                   ;    int r= *p+5;
LD      R2, [R1]           ;      R2=[R1]; // R2 = *p               ;    return r;
LD      R3, K5             ;      R3 = K5;                          ;  }
ADD     R4, R2, R3         ;      R4 = R2 + R3; // R4=*p+5          ;
ST      R4, r              ;      r = R4 // r = R4 = *p+5           ;
PUSH    R4                 ;      PUSH R4; // push return value     ;
RET                        ;      return;                           ;
K5      WORD    5                  ;      int K5=5;                         ;
r       RESW    1                  ;      int r;                            ;
END     MAIN               ;  }                                     ;```
```