【问题标题】:Function receiving null string函数接收空字符串
【发布时间】:2021-10-12 18:37:30
【问题描述】:

我有以下问题:我将一个字符串传递给一个函数,但是,当它接收到字符串时,它接收到一个空值并且什么都不做,我已经尝试解决它好几天了,但什么也没做,我认为这是 main() 函数中的错误

这是我的代码:

void main(){
   clear_screen();
   print_string("Hello World!"); 
}


void print_string(const char *string){
   int offset = get_cursor();
   int i = 0;
   while (string[i] != 0) {
      if(offset >= ROWS * COLS * 2) {
         offset = scroll_line(offset);
      }
      if(string[i] == '\n') {
         offset = move_offset_to_new_line(offset);
      }else{
         print_char(string[i], offset);
         offset += 2;
      }
      i++;
   }
   set_cursor(offset);
}

我的代码中会发生什么? 注意:我正在关注本网站上的示例:https://dev.to/frosnerd/writing-my-own-boot-loader-3mld

【问题讨论】:

  • 您确定包含字符串文字的图像部分已被引导加载程序正确加载到内存中,并且地址正确吗?
  • 是的,我可以使用 print_char() 函数编写字符,但是 print_string() 函数将字符串变量设为 null,我认为这是函数调用
  • 您是否在void print_string(const char *string) 的 main 之前声明了原型?或者更好地将该功能向上移动。函数必须在使用前声明
  • 是的,隐式声明是 int print_string(); 带有未指定的参数,所以它实际上应该仍然有效。至少我不明白它会如何导致声称的失败。
  • 如果你现在通过跳过偏移处理、光标处理和特殊字符处理来简化你的函数会发生什么?

标签: c osdev


【解决方案1】:

来自 cmets 的总结讨论:

本示例中的引导加载程序代码(不是在问题中,而是在链接站点中)经过硬编码以通过从磁盘读取 2 个扇区来加载内核。因此,这仅在内核映像大小小于 1 KB 时才有效。使用修改后的代码,您的图像结果超过 1 KB(实际上是 8 KB)。因此,您没有加载所有内容,特别是您没有加载包含字符串文字的图像部分。因此,当您访问它时,您会得到未初始化内存的内容,该内存显然以零字节开头,相当于一个空字符串。

您需要在编写更多代码并保持引导加载程序同步时跟踪内核映像的大小:查看load_kernel 后面的mov dh, 2 并将 2 替换为适当数量的 512 字节部门。对于一个更严肃的项目,你会想提出一个更强大的机制:例如内核映像的第一个扇区可以包含一个标头,该标头指定要读取多少个扇区。

大多数编译器和链接器设置会将字符串文字放入只读数据段(例如.rodata),与代码段(.text)分开,并将安排每个段占用第二组 4 KB 页,以便可以相应地设置页粒度内存权限(.text 的读取和执行,.rodata 的读取和不执行)。因此,即使您的代码和数据可能适合 1 KB,也可能需要将代码和数据放在单独的页面上,这可能是 8 KB 文件大小 (2 * 4 KB) 的原因。如果您添加读写数据(例如,不是const 的全局变量),您可能会看到另外 4 KB 的增加。

【讨论】:

    猜你喜欢
    • 2013-09-02
    • 2017-05-05
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-04
    • 2020-01-14
    • 2021-08-01
    相关资源
    最近更新 更多