初版 2026/02/09
改訂


func1.c

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

// 値渡し
//   関数内の変数は同名でも呼び出し元に影響しない
//   内部的には引数の変数がスタックに確保され、関数の終了で破棄される
void testFunc_byVal(uint8_t value) {
    value += 2;
}

// 参照渡し
//   与えられたポインタの値を直接更新するため、呼び出し元の変数の値にも反映される
//   対象のアドレスの値を直接操作するイメージ
void testFunc_byRef(uint8_t *value) {
    *value += 2;
}

void main() {

    uint8_t value = 5;

    printf("by val\n");
    testFunc_byVal(value);
    printf("value = %d\n", value);

    printf("by ref\n");
    testFunc_byRef(&value);
    printf("value = %d\n", value);

    return;
}
  • 関数の引数に変数名を指定すると、値渡しとなる。
  • 関数の引数にポインタを指定すると、参照渡しとなる。
  • 双方のアセンブリリストを比較すると、参照渡しにデコレータ__z88dk_fastcallを付けても、値渡しの方が速いという結果となった(値渡しは、__z88dk_fastcallを付けると逆に遅くなった)。

    • 値渡し

      呼び出し:42Tサイクル

      40  0026  2a0000                ld  hl,(_value)             ; 7
      40  0029  2600                  ld  h,0                     ; 7
      40  002b  e5                    push    hl                  ; 11
      40  002c  cd0000                call    _testFunc_byVal     ; 17
      

      関数:86Tサイクル

      15                          ._testFunc_byVal
      15  0000  210000                ld  hl,2    ;const          ; 7
      15  0003  39                    add hl,sp                   ; 11
      15  0004  e5                    push    hl                  ; 11
      15  0005  6e                    ld  l,(hl)                  ; 7
      15  0006  2600                  ld  h,0                     ; 7
      15  0008  23                    inc hl                      ; 6
      15  0009  23                    inc hl                      ; 6
      15  000a  d1                    pop de                      ; 10
      15  000b  7d                    ld  a,l                     ; 4
      15  000c  12                    ld  (de),a                  ; 7
      15  000d  c9                    ret                         ; 10
      
    • 参照渡し

      呼び出し:43Tサイクル

      40  004a  210000                ld  hl,_value               ; 7
      40  004d  e3                    ex  (sp),hl                 ; 19
      40  004e  cd0e00                call    _testFunc_byRef     ; 17
      

      関数:110Tサイクル

      23                          ._testFunc_byRef
      23  000e  c1                    pop bc                      ; 10
      23  000f  e1                    pop hl                      ; 10
      23  0010  e5                    push    hl                  ; 11
      23  0011  c5                    push    bc                  ; 11
      23  0012  e5                    push    hl                  ; 11
      23  0013  6e                    ld  l,(hl)                  ; 7
      23  0014  2600                  ld  h,0                     ; 7
      23  0016  23                    inc hl                      ; 6
      23  0017  23                    inc hl                      ; 6
      23  0018  d1                    pop de                      ; 10
      23  0019  7d                    ld  a,l                     ; 4
      23  001a  12                    ld  (de),a                  ; 7
      23  001b  c9                    ret                         ; 10
      

      関数にデコレータ__z88dk_factcallを付与:87Tサイクル

      23                          ._testFunc_byRef
      23  000e  e5                    push    hl                  ; 10
      23  000f  e5                    push    hl                  ; 10
      23  0010  6e                    ld  l,(hl)                  ; 7
      23  0011  2600                  ld  h,0                     ; 7
      23  0013  23                    inc hl                      ; 6
      23  0014  23                    inc hl                      ; 6
      23  0015  d1                    pop de                      ; 10
      23  0016  7d                    ld  a,l                     ; 4
      23  0017  12                    ld  (de),a                  ; 7
      23  0018  c1                    pop bc                      ; 10
      23  0019  c9                    ret                         ; 10
      


コンパイル

compile.sh

#!/bin/sh
zcc +msx -lmsxbios --list -subtype=msxdos $1.c -o $1.com


$ ./compile.sh ./func1


実行結果

2026-02-09-z88dk-c-func1_01.png

※MSXDOS.SYSとCOMMAND.COM、コンパイルして作成した.COMを配置したディレクトリをopenMSXでマウント、MSXDOSから実行