You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

32位保护模式下C语言打印函数开发问题求助

32位保护模式下批量打印字符串函数失效问题

我正在开发一款小型操作系统,已成功切换至32位保护模式以使用C语言替代汇编,但此时无法再使用interrupt 10h,必须直接向视频内存地址写入字符。我尝试编写一个print函数来批量打印字符串,而非逐个打印字符,但该函数始终无法正常工作,而单个字符打印的printChar函数却能正常运行。

C代码

void print(char* message, int offset);
void printChar(char character, int offset);

void start() {
    printChar('M', 2);
    print("Test String", 4);

    while (1) {

    }
}

void print(char* msg, int offset) {
    for (int i = 0; msg[i] != '\0'; i++)
    {
        printChar(msg[i], (i * 2) + offset);
    }
}

void printChar(char character, int offset) {
    unsigned char* vidmem = (unsigned char*)0xB8000;
    
    *(vidmem + offset + 1) = character;
    *(vidmem + offset + 2) = 0x0f;
}

编译与写入命令

使用以下命令将代码转换为二进制并通过sectedit写入软盘的第二个扇区:

gcc -c test.c
objcopy -O binary -j .text test.o test.bin

反汇编代码(objdump -d test.o输出)

0000000000000000 <start>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 20             sub    $0x20,%rsp
   8:   ba 02 00 00 00          mov    $0x2,%edx
   d:   b9 4d 00 00 00          mov    $0x4d,%ecx
  12:   e8 73 00 00 00          call   8a <printChar>
  17:   ba 04 00 00 00          mov    $0x4,%edx
  1c:   48 8d 05 00 00 00 00    lea    0x0(%rip),%rax        # 23 <start+0x23>
  23:   48 89 c1                mov    %rax,%rcx
  26:   e8 02 00 00 00          call   2d <print>
  2b:   eb fe                   jmp    2b <start+0x2b>

000000000000002d <print>:
  2d:   55                      push   %rbp
  2e:   48 89 e5                mov    %rsp,%rbp
  31:   48 83 ec 30             sub    $0x30,%rsp
  35:   48 89 4d 10             mov    %rcx,0x10(%rbp)
  39:   89 55 18                mov    %edx,0x18(%rbp)
  3c:   c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)
  43:   eb 29                   jmp    6e <print+0x41>
  45:   8b 45 fc                mov    -0x4(%rbp),%eax
  48:   8d 14 00                lea    (%rax,%rax,1),%edx
  4b:   8b 45 18                mov    0x18(%rbp),%eax
  4e:   01 c2                   add    %eax,%edx
  50:   8b 45 fc                mov    -0x4(%rbp),%eax
  53:   48 63 c8                movslq %eax,%rcx
  56:   48 8b 45 10             mov    0x10(%rbp),%rax
  5a:   48 01 c8                add    %rcx,%rax
  5d:   0f b6 00                movzbl (%rax),%eax
  60:   0f be c0                movsbl %al,%eax
  63:   89 c1                   mov    %eax,%ecx
  65:   e8 20 00 00 00          call   8a <printChar>
  6a:   83 45 fc 01             addl   $0x1,-0x4(%rbp)
  6e:   8b 45 fc                mov    -0x4(%rbp),%eax
  71:   48 63 d0                movslq %eax,%rdx
  74:   48 8b 45 10             mov    0x10(%rbp),%rax
  78:   48 01 d0                add    %rdx,%rax
  7b:   0f b6 00                movzbl (%rax),%eax
  7e:   84 c0                   test   %al,%al
  80:   75 c3                   jne    45 <print+0x18>
  82:   90                      nop
  83:   90                      nop
  84:   48 83 c4 30             add    $0x30,%rsp
  88:   5d                      pop    %rbp
  89:   c3                      ret

000000000000008a <printChar>:
  8a:   55                      push   %rbp
  8b:   48 89 e5                mov    %rsp,%rbp
  8e:   48 83 ec 10             sub    $0x10,%rsp
  92:   89 c8                   mov    %ecx,%eax
  94:   89 55 18                mov    %edx,0x18(%rbp)
  97:   88 45 10                mov    %al,0x10(%rbp)
  9a:   48 c7 45 f8 00 80 0b    movq   $0xb8000,-0x8(%rbp)
  a1:   00
  a2:   8b 45 18                mov    0x18(%rbp),%eax
  a5:   48 98                   cltq
  a7:   48 8d 50 01             lea    0x1(%rax),%rdx
  ab:   48 8b 45 f8             mov    -0x8(%rbp),%rax
  af:   48 01 c2                add    %rax,%rdx
  b2:   0f b6 45 10             movzbl 0x10(%rbp),%eax
  b6:   88 02                   mov    %al,(%rdx)
  b8:   8b 45 18                mov    0x18(%rbp),%eax
  bb:   48 98                   cltq
  bd:   48 8d 50 02             lea    0x2(%rax),%rdx
  c1:   48 8b 45 f8             mov    -0x8(%rbp),%rax
  c5:   48 01 d0                add    %rdx,%rax
  c8:   c6 00 0f                movb   $0xf,(%rax)
  cb:   90                      nop
  cc:   48 83 c4 10             add    $0x10,%rsp
  d0:   5d                      pop    %rbp
  d1:   c3                      ret
  d2:   90                      nop
  d3:   90                      nop
  d4:   90                      nop
  d5:   90                      nop
  d6:   90                      nop
  d7:   90                      nop
  d8:   90                      nop
  d9:   90                      nop
  da:   90                      nop
  db:   90                      nop
  dc:   90                      nop
  dd:   90                      nop
  de:   90                      nop
  df:   90                      nop

问题解决(编辑补充)

问题根源在于未在Linux发行版环境下操作,Windows环境所需配置未正确设置。切换到Linux虚拟机并微调代码后,函数可正常运行(offset设置不合理,之前在故障环境中能生效,但正常情况下不应如此)。

内容的提问来源于stack exchange,提问作者Malormar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 07:54:09