質問編集履歴
1
    
        title	
    CHANGED
    
    | 
         
            File without changes
         
     | 
    
        body	
    CHANGED
    
    | 
         @@ -1,3 +1,84 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            C言語とアセンブリ言語を使用して、printf()関数を自作し、SPIM上でその動作を確認する応用プログラムを作成したいのですが、va_listやva_arg等のマクロを使用せずに作成する方法がわかりません。
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            自分でできたところまでのソースコードを記載します。
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            以下C言語のソースコードです。
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            void print_char(char c) {
         
     | 
| 
      
 8 
     | 
    
         
            +
              char s[2];
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              s[0] = c;
         
     | 
| 
      
 11 
     | 
    
         
            +
              s[1] = '\0';
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              print_string(s)
         
     | 
| 
      
 14 
     | 
    
         
            +
            }
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            void myprintf(char *fmt, ...) {
         
     | 
| 
      
 17 
     | 
    
         
            +
              
         
     | 
| 
      
 18 
     | 
    
         
            +
              int i, argc = 0;
         
     | 
| 
      
 19 
     | 
    
         
            +
              char *s;
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              while (*fmt) {
         
     | 
| 
      
 22 
     | 
    
         
            +
                if (*fmt == '%') {
         
     | 
| 
      
 23 
     | 
    
         
            +
                  fmt++;
         
     | 
| 
      
 24 
     | 
    
         
            +
                  argc++;
         
     | 
| 
      
 25 
     | 
    
         
            +
                  switch (*fmt){
         
     | 
| 
      
 26 
     | 
    
         
            +
                    case 'd':
         
     | 
| 
      
 27 
     | 
    
         
            +
                      // Process of %d
         
     | 
| 
      
 28 
     | 
    
         
            +
                      i = *((int*) ((char *)&fmt + argc * sizeof(void *)) );
         
     | 
| 
      
 29 
     | 
    
         
            +
                      print_int(i);
         
     | 
| 
      
 30 
     | 
    
         
            +
                      break;
         
     | 
| 
      
 31 
     | 
    
         
            +
                    case 's':
         
     | 
| 
      
 32 
     | 
    
         
            +
                      // Process of %s
         
     | 
| 
      
 33 
     | 
    
         
            +
                      s = *((int*) ((char *)&fmt + argc * sizeof(void *)) );
         
     | 
| 
      
 34 
     | 
    
         
            +
                      print_string(s);
         
     | 
| 
      
 35 
     | 
    
         
            +
                      break;
         
     | 
| 
      
 36 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 37 
     | 
    
         
            +
                  }
         
     | 
| 
      
 38 
     | 
    
         
            +
                }else {
         
     | 
| 
      
 39 
     | 
    
         
            +
                  // print a character as it is 
         
     | 
| 
      
 40 
     | 
    
         
            +
                  print_char(*fmt);
         
     | 
| 
      
 41 
     | 
    
         
            +
                }
         
     | 
| 
      
 42 
     | 
    
         
            +
                fmt++;
         
     | 
| 
      
 43 
     | 
    
         
            +
              }
         
     | 
| 
      
 44 
     | 
    
         
            +
            }
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            int main() {
         
     | 
| 
      
 48 
     | 
    
         
            +
              myprintf("I am %s, my age is %d", "○○", ○);
         
     | 
| 
      
 49 
     | 
    
         
            +
              return 0;
         
     | 
| 
      
 50 
     | 
    
         
            +
            }
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            以下アセンブリ言語のソースコードです。
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
             .text
         
     | 
| 
      
 55 
     | 
    
         
            +
              .align  2
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            _print_int:
         
     | 
| 
      
 58 
     | 
    
         
            +
              subu  $sp, $sp, 24
         
     | 
| 
      
 59 
     | 
    
         
            +
              sw    $ra, 20($sp)
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
              li    $v0, 1  # 1: print_int
         
     | 
| 
      
 62 
     | 
    
         
            +
              syscall
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
              lw    $ra, 20($sp)
         
     | 
| 
      
 65 
     | 
    
         
            +
              addu  $sp, $sp, 24
         
     | 
| 
      
 66 
     | 
    
         
            +
              j     $ra
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            _print_string:
         
     | 
| 
      
 70 
     | 
    
         
            +
              subu  $sp, $sp, 24
         
     | 
| 
      
 71 
     | 
    
         
            +
              sw    $ra, 20($sp)
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              li    $v0, 4  # 4: print_string
         
     | 
| 
      
 74 
     | 
    
         
            +
              syscall
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              lw    $ra, 20($sp)
         
     | 
| 
      
 77 
     | 
    
         
            +
              addu  $sp, $sp, 24
         
     | 
| 
      
 78 
     | 
    
         
            +
              j     $ra
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            このとき、case’u’や’o’であったり、printfの他のサブセットの実装の仕方がわかりません。
         
     | 
| 
      
 81 
     | 
    
         
            +
            マクロを使わないのは、課題でそう指定されているからです。
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
      
 82 
     | 
    
         
            +
            同じ機能を果たすものを自分で作成するのは大丈夫です。
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
       3 
84 
     | 
    
         
             
            よろしくお願いいたします。
         
     |