瀏覽代碼

实现字符串操作函数

simon 10 月之前
父節點
當前提交
4e5987f22e
共有 5 個文件被更改,包括 229 次插入42 次删除
  1. 2 38
      README.md
  2. 2 0
      kernel/global.h
  3. 160 0
      lib/string.c
  4. 58 0
      lib/string.h
  5. 7 4
      makefile

+ 2 - 38
README.md

@@ -9,45 +9,9 @@ make 编译过程
 ```sh
 (base) ➜  os_kernel git:(master) ✗ make mk_dir
 (base) ➜  os_kernel git:(master) ✗ make mbr
-nasm -I boot/include/ boot/mbr.S -o Build/bin/mbr.bin
 (base) ➜  os_kernel git:(master) ✗ make loader
-nasm -I boot/include/ boot/loader.S -o Build/bin/loader.bin
-(base) ➜  os_kernel git:(master) ✗ make kernel
-i386-elf-gcc -Wall -I lib/ -I lib/kernel -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/main.c -o Build/main.o
-i386-elf-gcc -Wall -I lib/ -I lib/kernel -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/init.c -o Build/init.o
-i386-elf-gcc -Wall -I lib/ -I lib/kernel -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/interrupt.c -o Build/interrupt.o
-i386-elf-gcc -Wall -I lib/ -I lib/kernel -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes device/timer.c -o Build/timer.o
-nasm -f elf kernel/kernel.S -o Build/kernel.o
-nasm -f elf lib/kernel/print.S -o Build/print.o
-i386-elf-gcc -Wall -I lib/ -I lib/kernel -I lib/user/ -I kernel/ -I device/ -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes kernel/debug.c -o Build/debug.o
-i386-elf-ld -Ttext 0xc0001500 -e main Build/main.o Build/init.o Build/interrupt.o Build/timer.o Build/kernel.o Build/print.o Build/debug.o -o Build/bin/kernel.bin
+(base) ➜  os_kernel git:(master) ✗ make K
 (base) ➜  os_kernel git:(master) ✗ make create_img
-bximage -q -func=create -hd=30M ./hd30M.img
-========================================================================
-                                bximage
-  Disk Image Creation / Conversion / Resize and Commit Tool for Bochs
-                                  $Id$
-========================================================================
-
-The disk image './hd30M.img' already exists.  Are you sure you want to replace it?
-Please type yes or no. [no] yes
-
-Creating hard disk image './hd30M.img' with CHS=60/16/63 (sector size = 512)
-
-The following line should appear in your bochsrc:
-  ata0-master: type=disk, path="./hd30M.img", mode=flat
 (base) ➜  os_kernel git:(master) ✗ make hd
-dd if=./Build/bin/mbr.bin of=./hd30M.img bs=512 count=1 conv=notrunc
-1+0 records in
-1+0 records out
-512 bytes transferred in 0.001023 secs (500462 bytes/sec)
-dd if=./Build/bin/loader.bin of=./hd30M.img bs=512 count=4 seek=2 conv=notrunc
-2+1 records in
-2+1 records out
-1462 bytes transferred in 0.002619 secs (558222 bytes/sec)
-dd if=./Build/bin/kernel.bin of=./hd30M.img bs=512 count=200 seek=9 conv=notrunc
-16+1 records in
-16+1 records out
-8418 bytes transferred in 0.000408 secs (20635682 bytes/sec)
 (base) ➜  os_kernel git:(master) ✗ make run
-```
+```

+ 2 - 0
kernel/global.h

@@ -27,4 +27,6 @@
 #define IDT_DESC_ATTR_DPL0 ((IDT_DESC_P << 7) + (IDT_DESC_DPL0 << 5) + IDT_DESC_32_TYPE)
 #define IDT_DESC_ATTR_DPL3 ((IDT_DESC_P << 7) + (IDT_DESC_DPL3 << 5) + IDT_DESC_32_TYPE)
 
+#define NULL ((void *)0)
+
 #endif // __KERNEL_GLOBAL_H

+ 160 - 0
lib/string.c

@@ -0,0 +1,160 @@
+#include "string.h"
+#include "../kernel/debug.h"
+#include "../kernel/global.h"
+
+// 函数: _memset
+// 作用: 将dst_起始的size个字节设置为value
+// 参数: dst_ 为目标地址, value 为设置的值, size 为设置的字节数
+// 返回: 无
+void _memset(void *dst_, uint8_t value, uint32_t size)
+{
+    ASSERT(dst_ != NULL);
+    uint8_t *dst = (uint8_t *)dst_;
+    while (size--)
+    {
+        *dst++ = value;
+    }
+}
+// 函数: _memcpy
+// 作用: 将src_起始的size个字节复制到dst_起始地址
+// 参数: dst_ 为目标地址, src_ 为源地址, size 为复制的字节数
+// 返回: 无
+void _memcpy(void *dst_, const void *src_, uint32_t size)
+{
+    ASSERT(dst_ != NULL && src_ != NULL);
+    uint8_t *dst = (uint8_t *)dst_;
+    const uint8_t *src = (const uint8_t *)src_;
+    while (size--)
+    {
+        *dst++ = *src++;
+    }
+}
+// 函数: _memcmp
+// 作用: 比较两个内存区域的内容
+// 参数: a_ 为比较的地址1, b_ 为比较的地址2, size 为比较的字节数
+// 返回: 相等返回0, a_大于b_返回1, a_小于b_返回-1
+int8_t _memcmp(const void *a_, const void *b_, uint32_t size)
+{
+    const char *a = a_;
+    const char *b = b_;
+    ASSERT(a != NULL && b != NULL);
+    while (size--)
+    {
+        if (*a != *b)
+        {
+            return *a > *b ? 1 : -1;
+        }
+        a++;
+        b++;
+    }
+    return 0;
+}
+// 函数: _strcpy
+// 作用: 将字符串从src_复制到dst_
+// 参数: dst_ 为目标地址, src_ 为源地址
+// 返回: 目标地址
+char *_strcpy(char *dst_, const char *src_)
+{
+    ASSERT(dst_ != NULL && src_ != NULL);
+    char *r = dst_; // 用来返回目标地址
+    while ((*dst_++ = *src_++))
+        ;
+    return r;
+}
+// 函数: _strlen
+// 作用: 返回字符串的长度
+// 参数: str 为字符串
+// 返回: 字符串的长度
+uint32_t _strlen(const char *str)
+{
+    ASSERT(str != NULL);
+    const char *p = str;
+    while (*p++)
+        ;
+    return (uint32_t)(p - str - 1);
+}
+// 函数: _strcmp
+// 作用: 比较两个字符串
+// 参数: a_ 为比较的字符串1, b_ 为比较的字符串2
+// 返回: 相等返回0, a_大于b_返回1, a_小于b_返回-1
+int8_t _strcmp(const char *a_, const char *b_)
+{
+    ASSERT(a_ != NULL && b_ != NULL);
+    const char *a = a_;
+    const char *b = b_;
+    while (*a != 0 && *a == *b)
+    {
+        a++;
+        b++;
+    }
+    return *a < *b ? -1 : *a > *b;
+}
+// 函数: _strchr
+// 作用: 在字符串中查找字符
+// 参数: str 为字符串, ch 为要查找的字符
+// 返回: 找到返回地址, 未找到返回NULL
+char *_strchr(const char *str, const uint8_t ch)
+{
+    ASSERT(str != NULL);
+    while (*str != 0)
+    {
+        if (*str == ch)
+        {
+            return (char *)str;
+        }
+        str++;
+    }
+    return NULL;
+}
+// 函数: _strrchr
+// 作用: 在字符串中查找字符(从后往前)
+// 参数: str 为字符串, ch 为要查找的字符
+// 返回: 找到返回地址, 未找到返回NULL
+char *_strrchr(const char *str, const uint8_t ch)
+{
+    ASSERT(str != NULL);
+    const char *last_char = NULL;
+    // 从前往后查找字符,若存在 ch 字符,则将其地址赋值给 last_char,last_char 为最后一个 ch 字符的地址
+    while (*str != 0)
+    {
+        if (*str == ch)
+        {
+            last_char = str;
+        }
+        str++;
+    }
+    return (char *)last_char;
+}
+// 函数: _strcat
+// 作用: 将字符串src_连接到dst_后
+// 参数: dst_ 为目标地址, src_ 为源地址
+// 返回: 目标地址(连接后的字符串)
+char *_strcat(char *dst_, const char *src_)
+{
+    ASSERT(dst_ != NULL && src_ != NULL);
+    char *str = dst_;
+    while (*str++)
+        ;
+    --str;
+    while ((*str++ = *src_++))
+        ;
+    return dst_;
+}
+// 函数: _strchrs
+// 作用: 在字符串中查找字符出现的次数
+// 参数: str 为字符串, ch 为要查找的字符
+// 返回: 字符出现的次数
+uint32_t _strchrs(const char *str, uint8_t ch)
+{
+    ASSERT(str != NULL);
+    uint32_t ch_cnt = 0;
+    while (*str != 0)
+    {
+        if (*str == ch)
+        {
+            ch_cnt++;
+        }
+        str++;
+    }
+    return ch_cnt;
+}

+ 58 - 0
lib/string.h

@@ -0,0 +1,58 @@
+#ifndef __LIB_STRING_H
+#define __LIB_STRING_H
+#include "stdint.h"
+
+//---------------------- 实现字符串操作函数--------------------------
+// 函数: _memset
+// 作用: 将dst_起始的size个字节设置为value
+// 参数: dst_ 为目标地址, value 为设置的值, size 为设置的字节数
+// 返回: 无
+void _memset(void *dst_, uint8_t value, uint32_t size);
+// 函数: _memcpy
+// 作用: 将src_起始的size个字节复制到dst_起始地址
+// 参数: dst_ 为目标地址, src_ 为源地址, size 为复制的字节数
+// 返回: 无
+void _memcpy(void *dst_, const void *src_, uint32_t size);
+// 函数: _memcmp
+// 作用: 比较两个内存区域的内容
+// 参数: a_ 为比较的地址1, b_ 为比较的地址2, size 为比较的字节数
+// 返回: 相等返回0, a_大于b_返回1, a_小于b_返回-1
+int8_t _memcmp(const void *a_, const void *b_, uint32_t size);
+// 函数: _strcpy
+// 作用: 将字符串从src_复制到dst_
+// 参数: dst_ 为目标地址, src_ 为源地址
+// 返回: 目标地址
+char *_strcpy(char *dst_, const char *src_);
+// 函数: _strlen
+// 作用: 返回字符串的长度
+// 参数: str 为字符串
+// 返回: 字符串的长度
+uint32_t _strlen(const char *str);
+// 函数: _strcmp
+// 作用: 比较两个字符串
+// 参数: a_ 为比较的字符串1, b_ 为比较的字符串2
+// 返回: 相等返回0, a_大于b_返回1, a_小于b_返回-1
+int8_t _strcmp(const char *a_, const char *b_);
+// 函数: _strchr
+// 作用: 在字符串中查找字符(从前往后)
+// 参数: str 为字符串, ch 为要查找的字符
+// 返回: 找到返回地址, 未找到返回NULL
+char *_strchr(const char *str, const uint8_t ch);
+// 函数: _strrchr
+// 作用: 在字符串中查找字符(从后往前)
+// 参数: str 为字符串, ch 为要查找的字符
+// 返回: 找到返回地址, 未找到返回NULL
+char *_strrchr(const char *str, const uint8_t ch);
+// 函数: _strcat
+// 作用: 将字符串src_连接到dst_后
+// 参数: dst_ 为目标地址, src_ 为源地址
+// 返回: 目标地址(连接后的字符串)
+char *_strcat(char *dst_, const char *src_);
+// 函数: _strchrs
+// 作用: 在字符串中查找字符出现的次数
+// 参数: str 为字符串, ch 为要查找的字符
+// 返回: 字符出现的次数
+uint32_t _strchrs(const char *str, uint8_t ch);
+
+//---------------------- 实现字符串操作函数--------------------------
+#endif // __LIB_STRING_H

+ 7 - 4
makefile

@@ -12,7 +12,7 @@ CFLAGS = -Wall $(LIB) -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototype
 LDFLAGS = -Ttext $(ENTRY_POINT) -e main -Map $(BUILD_BIN_DIR)/kernel.map
 OBJS = $(BUID_O_DIR)/main.o $(BUID_O_DIR)/init.o $(BUID_O_DIR)/interrupt.o  \
 	$(BUID_O_DIR)/timer.o $(BUID_O_DIR)/kernel.o $(BUID_O_DIR)/print.o   \
-	$(BUID_O_DIR)/debug.o
+	$(BUID_O_DIR)/debug.o $(BUID_O_DIR)/string.o
 
 ################################ C 代码编译 ################################
 $(BUID_O_DIR)/main.o: kernel/main.c lib/kernel/print.h lib/stdint.h kernel/init.h
@@ -30,6 +30,9 @@ $(BUID_O_DIR)/timer.o: device/timer.c lib/stdint.h device/timer.h kernel/interru
 $(BUID_O_DIR)/debug.o: kernel/debug.c kernel/debug.h lib/kernel/print.h lib/stdint.h kernel/interrupt.h
 	$(CC) $(CFLAGS) $< -o $@
 
+$(BUID_O_DIR)/string.o: lib/string.c lib/string.h lib/stdint.h
+	$(CC) $(CFLAGS) $< -o $@
+
 ################################ 汇编代码编译 ################################
 $(BUID_O_DIR)/kernel.o: kernel/kernel.S
 	$(AS) $(ASFLAGS) $< -o $@
@@ -48,7 +51,7 @@ $(BUILD_BIN_DIR)/kernel.bin: $(OBJS)
 	$(LD) $(LDFLAGS) $^ -o $@
 
 
-.PHONY:clean mk_dir mbr loader kernel create_img hd run all
+.PHONY:clean mk_dir mbr loader K create_img hd run all
 
 mk_dir:
 	@if [ ! -d $(BUID_O_DIR) ]; then mkdir $(BUID_O_DIR); fi
@@ -69,7 +72,7 @@ clean:
 	rm -rf $(DIS_IMG)
 	rm -rf bochs_log.txt
 
-kernel: $(BUILD_BIN_DIR)/kernel.bin
+K: $(BUILD_BIN_DIR)/kernel.bin
 
 mbr: $(BUILD_BIN_DIR)/mbr.bin
 
@@ -78,4 +81,4 @@ loader: $(BUILD_BIN_DIR)/loader.bin
 run:
 	bochs -f bochsrc -q
 
-all: mk_dir create_img mbr loader kernel hd
+all: mk_dir create_img mbr loader K hd