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
相关产品推荐
相关产品推荐

