C 標準ライブラリ実装

教材には memcpy や strcmp が実装されていたので,練習がてら memcmp を実装する

int memcmp(const void *buf1, const void *buf2, size_t n){
    const uint8_t *p = (const uint8_t *)buf1;
    const uint8_t *t = (const uint8_t *)buf2;
    while(n--){
      if(*p != *t)
        return *p - *t;
      p++;
      t++;
    }
    return 0;
}

テストの追加

そういえばテストが無いので追加する.

void test_libc(void) {
    assert(memcmp("abc", "abc", 3) == 0);
    assert(memcmp("abc", "abd", 3) < 0);
    
    // strcmp
    assert(strcmp("hello", "hello") == 0);
    assert(strcmp("abc", "abd") < 0);
    assert(strcmp("apple", "app") > 0);
    
    // memcpy
    char buf[10];
    memcpy(buf, "hello", 6);
    assert(strcmp(buf, "hello") == 0);
    
    
    printf("All tests passed\n");
}

あとは assert

#define assert(expr) \
    do { \
        if (!(expr)) { \
            printf("Assertion failed: %s at %s:%d\n", #expr, __FILE__, __LINE__); \
            for (;;); \
        } \
    } while (0)

実行結果

u@u-VirtualBox:~/French_Cruller$ ./run.sh 
+ QEMU=qemu-system-riscv32
+ CC=clang
+ CFLAGS='-std=c11 -O2 -g3 -Wall -Wextra --target=riscv32-unknown-elf -fuse-ld=lld -fno-stack-protector -ffreestanding -nostdlib'
+ clang -std=c11 -O2 -g3 -Wall -Wextra --target=riscv32-unknown-elf -fuse-ld=lld -fno-stack-protector -ffreestanding -nostdlib -Wl,-Tkernel.ld -Wl,-Map=kernel.map -o kernel.elf kernel.c common.c
+ qemu-system-riscv32 -machine virt -bios default -nographic -serial mon:stdio --no-reboot -kernel kernel.elf

OpenSBI v1.7
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|

Platform Name               : riscv-virtio,qemu
Platform Features           : medeleg
Platform HART Count         : 1
Platform IPI Device         : aclint-mswi
Platform Timer Device       : aclint-mtimer @ 10000000Hz
Platform Console Device     : uart8250
Platform HSM Device         : ---
Platform PMU Device         : ---
Platform Reboot Device      : syscon-reboot
Platform Shutdown Device    : syscon-poweroff
Platform Suspend Device     : ---
Platform CPPC Device        : ---
Firmware Base               : 0x80000000
Firmware Size               : 313 KB
Firmware RW Offset          : 0x40000
Firmware RW Size            : 57 KB
Firmware Heap Offset        : 0x45000
Firmware Heap Size          : 37 KB (total), 2 KB (reserved), 10 KB (used), 24 KB (free)
Firmware Scratch Size       : 4096 B (total), 1340 B (used), 2756 B (free)
Runtime SBI Version         : 3.0
Standard SBI Extensions     : time,rfnc,ipi,base,hsm,srst,pmu,dbcn,fwft,legacy,dbtr,sse
Experimental SBI Extensions : none

Domain0 Name                : root
Domain0 Boot HART           : 0
Domain0 HARTs               : 0*
Domain0 Region00            : 0x00100000-0x00100fff M: (I,R,W) S/U: (R,W)
Domain0 Region01            : 0x10000000-0x10000fff M: (I,R,W) S/U: (R,W)
Domain0 Region02            : 0x02000000-0x0200ffff M: (I,R,W) S/U: ()
Domain0 Region03            : 0x80040000-0x8004ffff M: (R,W) S/U: ()
Domain0 Region04            : 0x80000000-0x8003ffff M: (R,X) S/U: ()
Domain0 Region05            : 0x0c400000-0x0c5fffff M: (I,R,W) S/U: (R,W)
Domain0 Region06            : 0x0c000000-0x0c3fffff M: (I,R,W) S/U: (R,W)
Domain0 Region07            : 0x00000000-0xffffffff M: () S/U: (R,W,X)
Domain0 Next Address        : 0x80200000
Domain0 Next Arg1           : 0x87e00000
Domain0 Next Mode           : S-mode
Domain0 SysReset            : yes
Domain0 SysSuspend          : yes

Boot HART ID                : 0
Boot HART Domain            : root
Boot HART Priv Version      : v1.12
Boot HART Base ISA          : rv32imafdch
Boot HART ISA Extensions    : sstc,zicntr,zihpm,zicboz,zicbom,sdtrig,svadu
Boot HART PMP Count         : 16
Boot HART PMP Granularity   : 2 bits
Boot HART PMP Address Bits  : 32
Boot HART MHPM Info         : 16 (0x0007fff8)
Boot HART Debug Triggers    : 2 triggers
Boot HART MIDELEG           : 0x00001666
Boot HART MEDELEG           : 0x00f0b509
All tests passed

OK