汇编语言显示中文

由于emum8088CPU支持ASCII字符集,不支持Unicode字符集,需要我们用点阵的形式显示汉字。

首先需要获得汉字的点阵表示形式,即16*16的表示,32个字节。

汉字在Unicode字符集中,由两个字节表示,前一个表示区号,后一个表示偏移地址。

字体库 放在了D盘目录下面:

#include <stdio.h>
int main(void)
{
FILE* fphzk = NULL;
errno_t err;
int i, j, k, offset;
int flag;
unsigned char buffer[32];
unsigned char word[3] = “我”;
unsigned char key[8] = {
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01
};

//fphzk = fopen("D:/hzk16k", "rb");
err = fopen_s(&fphzk, "D:/hzk16k", "rb" );     //楷体显示的字符
if (fphzk == NULL) {
    fprintf(stderr, "error hzk16\n");
    return 1;
}
offset = (94 * (unsigned int)(word[0] - 0xa0 - 1) + (word[1] - 0xa0 - 1)) * 32;
fseek(fphzk, offset, SEEK_SET);
fread(buffer, 1, 32, fphzk);
for (k = 0; k < 32; k++) {
    printf("%02X ", buffer[k]);
}
for (k = 0; k < 16; k++) {
    for (j = 0; j < 2; j++) {
        for (i = 0; i < 8; i++) {
            flag = buffer[k * 2 + j] & key[i];
            printf("%s", flag ? "●" : "○");
        }
    }
    printf("\n");
}
fclose(fphzk);
fphzk = NULL;
return 0;

}
在这里插入图片描述

如上图,获得了汉字 “我”的点阵表达形式。

”我的计算机工作正常“ 点阵表示:

WORD1 DB 01H,00H,01H,00H,01H,20H,05H,10H,19H,00H,09H,70H,0FH,80H,38H,90H,0AH,0A0H,0CH,40H,38H,0C0H,0CBH,24H,18H,14H,08H,0CH,00H,04H,00H,00H
WORD2 DB 00H,00H,00H,20H,08H,20H,08H,40H,10H,58H,2CH,0E8H,75H,08H,46H,88H,74H,48H,44H,48H,44H,08H,3CH,08H,24H,28H,00H,10H,00H,00H,00H,00h
WORD3 DB 00H,40H,10H,40H,08H,40H,00H,40H,00H,40H,30H,7CH,0D3H,0C0H,10H,40H,10H,40H,14H,40H,18H,40H,10H,40H,00H,40H,00H,40H,00H,40H,00H,00H
word4 db 08H,58H,0FH,60H,08H,90H,15H,00H,23H,0C0H,04H,40H,07H,40H,04H,40H,07H,0C0H,04H,7EH,7FH,0C0H,04H,40H,04H,40H,08H,40H,10H,40H,00H,00H
word5 db 10H,00H,10H,00H,10H,00H,10H,70H,1CH,90H,70H,0A0H,10H,0A0H,18H,0A0H,34H,0A0H,51H,22H,91H,22H,12H,1EH,14H,00H,10H,00H,00H,00H,00H,00H
word6 db 00H,00H,00H,00H,00H,00H,00H,0E0H,0FH,00H,01H,00H,01H,00H,01H,00H,01H,00H,01H,00H,01H,0FCH,7EH,00H,00H,00H,00H,00H,00H,00H,00H,00H
word7 db 00H,40H,08H,40H,08H,80H,08H,9CH,11H,0E0H,31H,40H,52H,40H,94H,78H,10H,40H,10H,40H,10H,78H,10H,40H,10H,40H,00H,40H,00H,40H,00H,00H
word8 db 00H,00H,00H,00H,00H,0F0H,0FH,00H,01H,00H,01H,00H,09H,30H,09H,0C0H,09H,00H,09H,00H,09H,00H,09H,0FCH,0FEH,00H,00H,00H,00H,00H,00H,00H
word9 db 01H,20H,09H,40H,05H,00H,0FH,0F8H,70H,08H,4FH,0D0H,48H,80H,07H,00H,01H,0E0H,0FH,20H,09H,20H,09H,60H,09H,20H,01H,00H,01H,00H,00H,00H
  接下里就是那些汇编程序:

DATAS SEGMENT
;字模数据,可用字模生成程序生成,替换掉此处即可,此处使用的是16*16的黑体字模,32byte/字
TW DB 01H,00H,01H,00H,01H,20H,05H,10H,19H,00H,09H,70H,0FH,80H,38H,90H,0AH,0A0H,0CH,40H,38H,0C0H,0CBH,24H,18H,14H,08H,0CH,00H,04H,00H,00H
DB 00H,00H,00H,20H,08H,20H,08H,40H,10H,58H,2CH,0E8H,75H,08H,46H,88H,74H,48H,44H,48H,44H,08H,3CH,08H,24H,28H,00H,10H,00H,00H,00H,00h
DB 00H,40H,10H,40H,08H,40H,00H,40H,00H,40H,30H,7CH,0D3H,0C0H,10H,40H,10H,40H,14H,40H,18H,40H,10H,40H,00H,40H,00H,40H,00H,40H,00H,00H
db 08H,58H,0FH,60H,08H,90H,15H,00H,23H,0C0H,04H,40H,07H,40H,04H,40H,07H,0C0H,04H,7EH,7FH,0C0H,04H,40H,04H,40H,08H,40H,10H,40H,00H,00H
db 10H,00H,10H,00H,10H,00H,10H,70H,1CH,90H,70H,0A0H,10H,0A0H,18H,0A0H,34H,0A0H,51H,22H,91H,22H,12H,1EH,14H,00H,10H,00H,00H,00H,00H,00H
db 00H,00H,00H,00H,00H,00H,00H,0E0H,0FH,00H,01H,00H,01H,00H,01H,00H,01H,00H,01H,00H,01H,0FCH,7EH,00H,00H,00H,00H,00H,00H,00H,00H,00H
db 00H,40H,08H,40H,08H,80H,08H,9CH,11H,0E0H,31H,40H,52H,40H,94H,78H,10H,40H,10H,40H,10H,78H,10H,40H,10H,40H,00H,40H,00H,40H,00H,00H
db 00H,00H,00H,00H,00H,0F0H,0FH,00H,01H,00H,01H,00H,09H,30H,09H,0C0H,09H,00H,09H,00H,09H,00H,09H,0FCH,0FEH,00H,00H,00H,00H,00H,00H,00H
db 01H,20H,09H,40H,05H,00H,0FH,0F8H,70H,08H,4FH,0D0H,48H,80H,07H,00H,01H,0E0H,0FH,20H,09H,20H,09H,60H,09H,20H,01H,00H,01H,00H,00H,00H
DATAS ENDS

STACKS SEGMENT
DW 10 DUP(?)
STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX ;设置数据段寄存器

MOV AX,STACKS
MOV SS,AX           ;设置栈段寄存器
MOV SP,20           ;设置栈顶偏移地址

MOV AH,0FH 
INT 10H             ;读当前显示方式至AX中

PUSH AX             ;当前显示方式入栈

MOV AX,12H  
INT 10H             ;设置显示方式为VGA彩色

MOV DI,(30 * 80 + 10) * 2         ;DI控制显示位置,640*480分辨率,可显示80*60字节,第i行汉字写入时DI为80*16*i~80*16*i+78,相邻汉字DI差2
CALL DISPLAY            ;调用显示过程

MOV AH,01
INT 21H             ;等待输入,暂停作用

POP AX              ;AX出栈
MOV AH,00H
INT 10H             ;恢复原来显示方式

MOV AX,4C00H            ;退出程序
INT 21H

;MOVSW指令将DS:SI中数据按字传送至ES:DI

DISPLAY:    
;输出 ‘我的计算机工作正常’--------------------
    MOV AX,0A000H           ;VGA写入起始段地址
    MOV ES,AX           ;设置传送目标段地址
    CLD             ;CLD指令使DF=0,正向传输字
    MOV CX,9            ;连续的字数,此处“我的计算机工作正常”共9字
    LEA SI,TW           ;需写入汉字字模的首地址
    DIS1:
        PUSH CX         ;多重循环,CX入栈
        PUSH SI
        PUSH DI
        MOV CX,16
        DISWORD1:
            MOVSW
            ADD DI,78   ;转到下一行字模写入位置,一个汉字16*16,故需写16行
        LOOP DISWORD1
        POP DI
        POP SI
        POP CX
        ADD SI,32       ;读取下一个汉字的字模数据,由于一个汉字占用32byte,故加上32
        ADD DI,2        ;开始写下一个汉字,默认写在上一个字右边
    LOOP DIS1
RET
;-----------------------------

在这里插入图片描述

  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值