实现字符打印(实验)

stdint.h

#ifndef __LIB_STDINT_H
#define __LIB_STDINT_H
typedef signed char int8_t;
typedef signed short int int16_t;
typedef signed int int32_t;
typedef signed long long int int64_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
#endif

print.h

#ifndef __LIB_KERNEL_PRINT_H
#define __LIB_KERNEL_PRINT_H
#include "stdint.h"

void put_char(uint8_t char_asci);
#endif

print.S

在这里插入图片描述

RPL0    equ 00b
TI_GDT  equ 000b
SELECTOR_VIDEO       equ (0X0003<<3) + TI_GDT + RPL0 
SELECTOR_DATA	  equ (0X0002<<3) + TI_GDT + RPL0


[bits 32]
section .text
global put_char
;------------------- put_char 函数实现 -------------------------------------------
;把字符写到光标位置
;---------------------------------------------------------------------------------

put_char:

    pushad           		;push all double寄存器
    mov ax,SELECTOR_VIDEO
    mov gs,ax                  ;gs寄存器赋值段选择子
    
    mov dx,0x3D4               ;默认CRT 寄存器索引
    mov al,0xE                 ;这里用al 不用ax 是因为 此处索引寄存器是一个8字节的寄存器
    out dx,al                  ;看光标高位值寄存器 为什么用al 可以推算一下 光标0~1999 2^(8+8)字节完全够用
    mov dx,0x3D5               ;光标高位值寄存器窗口
    in  al,dx                  ;移入ax 
    shl ax,0x8                 ;左移动8位 移动向ah部分 光标位置为8字节
    
    mov dx,0x3D4
    mov al,0xF
    out dx,al
    mov dx,0x3D5
    in  al,dx
    
    mov bx,ax                  ;光标位置转移给bx  
    mov byte cl,[esp+36]       ;4字节返回 只需要把push eip 4字节 + pushad 8*4 32字节算进去即可
                               
                               ;回车0xd 换行0xa 退格0x8 
    cmp cl,0xd                 ;比较cl与0xd是否相等
    je .is_carriage_return     ;回车处理函数
    cmp cl,0xa                 ;比较cl与0xa是否相等 
    je .is_line_feed           ;换行处理函数
    cmp cl,0x8                 ;比较cl与0x8是否相等
    je .is_backspace           ;退格处理函数
    
    jmp .put_other_char
       
 .is_backspace:
    cmp bx,0                   ;如果bx = 0 则没有办法退格了 这是我除书上之外额外加的条件
    je  .set_cursor              
    
    dec bx                     ;光标位置退1
    shl bx,1                   ;一个字符占两个字节 一个字节是属性 一个字节ascii 
    
    mov word [gs:bx],0x0720    ;低字节ascii 32 ascii表示空字符 7 高字符属性空
    shr bx,1                   ;退回原来的位置
    jmp .set_cursor            ;交给硬件去处理光标位置 到时候在那几个老端口把字符信息还回去就完事了
    
 .put_other_char:
    shl bx,1                   
    mov [gs:bx],cl             
    inc bx                     
    mov byte [gs:bx],0x7
    inc bx
    shr bx,1
    cmp bx,2000                ;没到边界2000即跳转
    jl  .set_cursor            ;没有的话 继续往下进行 都2000了其实下面的操作也是不能跳转走的
                               ;只能等下面继续处理滚动屏幕了
                               
    
 .is_carriage_return:
 .is_line_feed:
    xor dx,dx
    mov ax,bx                  ;32位除以16位 被除数高位dx 被除数低位ax div之后余数放在dx 商放在ax
    mov si,80
    div si
    sub bx,dx
    
 .is_carrige_return_end:
    add bx,80                  ;一共一页2000252000/25=80 则向bx增加80
    cmp bx,2000
    jl .set_cursor             
    
 .roll_screen:
    cld                        ;从低到高移动
    mov ax,SELECTOR_DATA 	;我不放心 就初始化了一下
    mov es,ax      
    mov di,es                  
    mov ecx,920
    
    mov esi,0xc00b80a0          ;忘了的这里写一下 ds:si -> es:di (s->d) 源地址si 目的地址di  
    mov edi,0xc00b8000
    rep movsd                  ;movs doubleword 双子
    
    mov ebx,3840               ;最后一行80*2 = 160 4000-160 = 3840 最后一行清除了
    mov ecx,80
    mov esi,0                  
    
 .clean_last_row:   
    mov word [ebx+esi*2],0x720 ;0x07 0x20 属性 空字符
    inc esi     
    loop .clean_last_row
    
    mov ebx,1920
    
 .set_cursor:
    mov dx,0x3D4
    mov al,0xE
    out dx,al
    mov dx,0X3D5
    mov al,bh
    out dx,al
    
    mov dx,0x3D4
    mov al,0XF
    out dx,al
    mov dx,0x3D5
    mov al,bl
    out dx,al
    
    popad                        ;把之前全部储存的给pop出来 还原现场
    ret

mian.c

#include "print.h"
int main()
{	
  put_char('k');
  put_char('e');
  put_char('r');
  put_char('n');
  put_char('e');
  put_char('l');
  put_char('!');
  put_char('\n');
  put_char('i');
  put_char('m');
  put_char(' ');
  put_char('c');
  put_char('o');
  put_char('m');
  put_char('1'); //这里的1是看退格是否生效 
                 //输出时只要是kernel! im coming!即可
  put_char('\b');
  put_char('i');
  put_char('n');
  put_char('g');
  put_char('!');
  while(1);
  return 0;
}

实验

sudo nasm -f elf -o  print.o print.S
sudo gcc -m32 -I kernel/ -c -o kernel/main.o kernel/main.c


sudo ld -m elf_i386  -Ttext 0xc0001500 -e main -o kernel/kernel.bin kernel/main.o kernel/print.o


sudo dd if=/usr/local/bin/kernel/kernel.bin of=/usr/local/bin/hd60M.img bs=512 count=200 seek=9 conv=notrunc

实现字符串打印

print.S

;先自己尝试写一下 
global put_str   
put_str:
    push eax
    push ebx
    push ebp
    xor  eax,eax
    mov  ebp,esp                 ;一般用ebp来寻值 esp上面有个4字节的返回地址 就没有了
    mov  ebx,[ebp+16]            ;指针4字节+12字节寄存器
    
 .put_char_loop:    
    mov byte al,[ebx]
    cmp  al,0
    je  .str_end
    push ax
    call put_char
    add  esp,2
    inc  ebx
    jmp .put_char_loop
    
 .str_end:
    pop ebp
    pop ebx
    pop eax
    ret

main.c

#include "print.h"
int main()
{	
   
   put_str("kernel!\nim com1\bing!");
   put_str("\n");
   put_str("");
   put_str("g");
   put_char('g');
   while(1);
   return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 基于MATLAB的字符识别是一种通过使用MATLAB软件进行字符(汉字、字母、数字等)的自动识别技术。该技术结合了图像处理和机器学习算法,可以识别不同的字符,并将其转化为可供计算机进一步处理的数据格式。 首先,需要进行图像预处理,包括图像的灰度化、二值化、去噪等操作,以使得字符在图像上更加明显和清晰可见。接着,通过字符特征提取算法,将字符从图像中分离出来,并获得其特征描述。 在训练阶段,使用已知的字符样本集,利用机器学习算法(如支持向量机、神经网络等)进行训练模型的构建。训练模型可根据已知字符的特征和标签,学习到特征和字符之间的映射关系。这样在识别阶段,可以根据输入的待识别字符的特征,通过训练好的模型,对字符进行分类。 最后,基于分类结果,输出识别结果,可以是字符的标签、字符的文本内容等。 基于MATLAB实现字符识别具有较高的准确率和鲁棒性,并且易于使用和调试。MATLAB作为一种多功能的编程环境,提供了丰富的图像处理和机器学习工具箱,可以方便地进行实验和算法的实现。通过不断优化算法和模型,以及增加训练样本,可以进一步提高识别准确率。字符识别在许多领域有着广泛的应用,如自动邮件分拣、车牌识别、身份证识别等。 ### 回答2: 基于matlab的字符识别是一种常见的图像处理技术,用于将图像中的字符准确地识别出来。在使用matlab实现字符识别时,通常会采取以下步骤: 1. 图像预处理:首先,对目标图像进行预处理,包括图像灰度化、二值化、去噪等操作。这一步旨在提高图像的质量,便于后续字符的分割和识别。 2. 字符分割:将预处理后的图像分割成单个字符,通常采用基于连通区域的分割算法。该算法可通过分析字符间的空白区域来实现字符的精确分割。 3. 特征提取:对每个分割出的字符进行特征提取,常用的特征有灰度特征、形态学特征、统计特征等。特征提取的目的是减少字符的维度,提取出关键信息,方便后续的分类与识别。 4. 字符分类:利用机器学习算法对提取的特征进行分类,常用的算法有支持向量机(SVM)、神经网络等。通过训练样本集和测试样本集,将未知字符识别为已知的具体字符。 5. 字符识别:根据分类结果,即可将图像中的字符准确地识别出来,并输出相应的结果。如果需要识别的是连续字符串,还可以通过组合多个字符的识别结果来得到完整的字符串。 基于matlab实现字符识别具有较高的准确性和稳定性,能快速而准确地识别出图像中的字符。该技术在许多领域都有广泛应用,如自动识别邮件验证码、实现光学字符识别(OCR)等。 ### 回答3: 基于Matlab实现字符识别是一种通过训练模型和图像处理技术来识别和分类字符的方法。以下是实现字符识别的一般步骤: 1. 数据收集:收集包含不同字符的图像数据集。这些数据可以包括手写字母、打印字体、数字等。 2. 图像预处理:对收集到的图像进行预处理,包括调整图像大小、去除噪声、灰度化和二值化等操作,以便后续处理。 3. 特征提取:从预处理的图像中提取特征,常见的特征包括形态学特征、纹理特征和投影特征等。 4. 模型训练:使用提取到的特征,建立分类模型,常见的模型包括支持向量机(SVM)、人工神经网络(ANN)和决策树等。 5. 模型评估:使用测试数据集来评估训练好的模型的准确性和鲁棒性。 6. 字符识别:使用训练好的模型对新的字符图像进行识别和分类。 7. 优化调整:根据实际应用的需求,对模型进行优化调整,以提高识别准确性和性能。 基于Matlab实现字符识别具有以下优势: 1. 简便易用:Matlab提供了丰富的图像处理和机器学习工具包,可以方便地实现字符识别算法。 2. 强大的算法支持:Matlab提供了各种常用的图像处理和机器学习算法,如形态学处理、特征提取、SVM、ANN等,可以满足不同需求。 3. 丰富的可视化功能:Matlab具有强大的可视化功能,可以方便地对图像进行可视化处理,如显示、标记、绘制边界框等。 4. 广泛的应用领域:字符识别在许多领域有着广泛的应用,如自动化、文字识别、人机交互等。基于Matlab的字符识别可以方便地应用在这些领域中。 综上所述,基于Matlab实现字符识别是一种方便、高效且可靠的方法,可以用于各种字符识别的应用场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值