8086汇编和c语言混合实现操作系统Word文档下载推荐.docx
- 文档编号:22667340
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:53
- 大小:309.60KB
8086汇编和c语言混合实现操作系统Word文档下载推荐.docx
《8086汇编和c语言混合实现操作系统Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《8086汇编和c语言混合实现操作系统Word文档下载推荐.docx(53页珍藏版)》请在冰豆网上搜索。
向当前光标位置输出字符串
字符串首地址
输出字符个数
externchar*gets(char*str);
读取字符串
externintstrlen(constchar*str);
求以0结束的字符串的长度
字符从长度
externintgetchar(void);
读取字符
字符的ascii码
externintputchar(intc);
输出字符
字符c
externunsignedintport_in8(unsignedintport);
从port端口读入8位数据
端口号
读取的数据
externunsignedintport_in16(unsignedintport);
从port端口读入16位数据
externvoidport_out8(unsignedintport,unsignedintvalue);
向port端口输出8位数据value
端口号和数据
无
externvoidport_out16(unsignedintport,unsignedintvalue);
从port端口输出16位数据value
externvoidsetp_cursor(unsignedintbh,unsignedintdh,unsignedintdl);
将第bh页的指针置于dh行dl列
页号bh,行号dh,列号dl
externvoidrun_pro(intord);
运行程序地址表中第ord号程序
程序序号
b)主控制程序:
osc.c
externintputs(constchar*str);
voidinttostr(intx,char*str);
intstrtoint(char*str);
unsignedintbcdtodex(unsignedintx);
voidget_date(char*buf);
/*yy-mm-dd*/
voidset_date(char*buf);
voidget_time(char*buf);
/*hh:
mm:
ss*/
voidset_time(char*buf);
voidpre_time();
voidinterface();
intstrcmp(charstr1[],charstr2[]);
voidatoA(char*buf);
intdeal(char*buf);
intinside(intmin,intmax,intx);
intchange_time(intparas);
intislegal(inty,intm,intd);
intchange_date(intparas);
intshutdown(intparas);
intreboot(intparas);
intjc(intparas,char*buf);
charbuffer[80];
intcontrol=1;
charExit_Message[30]="
\nPressanykeytoexit..."
;
unsignedintadd_Table[30]={0x9000,0,0xa000,0,0xb000,0};
cmain(){
intparas;
control=0;
while
(1)
{
cls();
interface();
gets(buffer);
setp_cursor(0,6,0);
paras=deal(buffer);
if(paras!
=0)
{
jc(paras,buffer);
puts(Exit_Message);
getchar();
}
}
}
c)用户程序:
cx0.ccx1.c
2、实验步骤、操作的主要过程、运行结果、屏幕画面截图等
A.实验步骤
a)编写代码
b)在dosbox上执行批处理文件0.bat,得到,执行9000.bat得到用户程序1,执行a000.bat得到用户程序2
c)使用WinHex将中7e00h到结束的所有数据写到虚拟软盘文件Tinix.img偏移为0的位置处,将用户程序1和用户程序2对应的代码写到1400h和2400h处。
d)从软盘启动虚拟机
B.屏幕截图
a)开机界面
b)时间设置
c)日期设置
d)运行程序地址表中的用户程序
e)指令参数错误检查
f)执行重启命令,由于重启时无法截图,只提供命令输入界面
g)关机指令
C.指令总结
a)Time修改cmos时间,不需要参数
b)Date修改cmos日期,不需要参数
c)Runx执行第x号用户程序,1<
=x<
=2,安装新程序x需扩展。
d)Reboot重启,不需要参数
e)Shutdown关机,不需要参数
四、实验心得体会
A.程序c语言环境的配置和实现,应基于编译器tcc默认的调用规范cdecl。
a)cdecl在8086上对c语言参数的入栈顺序为从右向左入栈,对栈的恢复由程序调用者caller实现,汇编实现c语言函数库时,不需要在函数中对栈进行恢复。
在汇编程序中调用c实现的函数,对参数压栈和对函数返回后要注意恢复。
b)cdecl对函数的返回值,8位,16位和32位分别存放于al、ax、dx和ax中,汇编中调用c实现的函数时返回值的获取为以上寄存器。
c)cdecl只对ds,ss,bp,si,di等寄存器进行保护。
当在汇编中调用c实现的函数时,若通用寄存器ax,bx,cx,dx中存在有意义的值,要自行进行压栈保护。
B.实现tcc的过程中,发现tcc在栈的处理上存在bug。
tcc编译tcc_bug文件得到的二进制文件,通过debug反汇编解析,发现,tcc对函数中的临时字符串buf的取值从[bx+offset]中取(产生错误的位置在tcc_bug.c文件中有标注),而bx默认的段地址为ds而不是ss。
当ds不等于ss时,会取出错误的值,产生乱码。
解决方法:
通过在引导程序中配置c语言环境时ds和ss设置相同的值,成功解决产生乱码的问题。
C.由于8086程序在dos上运行是使用int21h的4ch号功能返回控制台,本次实验对安装了仅有单个iret指令的21h中断,来实现初步对dos程序的小的兼容,用于与用户的c语言链接的启动程序使用int21h调用安装的iret进行返回控制台。
Osc.c
/*control=1;
*/
voidinttostr(intx,char*str)
{
intl=0;
inti,offset;
charbuf[10];
if(x==0)
str[0]='
0'
str[1]=0;
return;
if(x<
0)
x=-x;
offset=1;
-'
else
offset=0;
while(x>
buf[l]=x%10+'
x=x/10;
l++;
for(i=0;
i<
l;
++i)
str[l-i-1+offset]=buf[i];
str[l+offset]=0;
intstrtoint(char*str)
intlen=strlen(str);
inti;
intsou;
intp;
intans;
if(str[0]=='
)
sou=1;
p=-1;
sou=0;
p=1;
ans=0;
for(i=sou;
len;
ans=ans*10+(str[i]-'
);
returnans*p;
unsignedintbcdtodex(unsignedintx)
return(x>
>
4)*10+(x&
0xf);
voidget_date(char*buf)/*yy-mm-dd*/
unsignedinty,m,d;
port_out8(0x70,9);
/*获取年*/
y=port_in8(0x71)&
0xff;
buf[0]=(y>
4)+'
buf[1]=(y&
0xf)+'
buf[2]='
port_out8(0x70,8);
/*获取月*/
m=port_in8(0x71)&
buf[3]=(m>
buf[4]=(m&
buf[5]='
port_out8(0x70,7);
/*获取日*/
d=port_in8(0x71)&
buf[6]=(d>
buf[7]=(d&
buf[8]=0;
voidset_date(char*buf)
y=((buf[0]-'
)<
<
4)+buf[1]-'
port_out8(0x71,y);
m=((buf[3]-'
4)+buf[4]-'
port_out8(0x71,m);
d=((buf[6]-'
4)+buf[7]-'
port_out8(0x71,d);
voidget_time(char*buf)/*hh:
unsignedinth,m,s;
port_out8(0x70,4);
/*获取时*/
h=port_in8(0x71)&
buf[0]=(h>
buf[1]=(h&
:
'
port_out8(0x70,2);
/*获取分*/
port_out8(0x70,0);
/*获取秒*/
s=port_in8(0x71)&
buf[6]=(s>
buf[7]=(s&
voidset_time(char*buf)
h=((buf[0]-'
port_out8(0x71,h);
s=((buf[6]-'
port_out8(0x71,s);
voidpre_time()
charbuf[20];
/*setp_cursor(0,1,62);
/*puts("
Time:
"
setp_cursor(0,1,70);
get_time(buf);
puts(buf);
/*setp_cursor(0,2,62);
Date:
setp_cursor(0,2,70);
get_date(buf);
voidinterface()
intpos[4];
pos[0]=0;
pos[1]=8;
pos[2]=60;
pos[3]=79;
cls();
setp_cursor(0,0,0);
80;
putchar('
='
4;
setp_cursor(0,1,pos[i]);
|'
setp_cursor(0,2,pos[i]);
setp_cursor(0,3,0);
setp_cursor(0,1,2);
puts("
Lab03"
setp_cursor(0,1,62);
/*把以下部分放到pre_time,乱码,寻址问题?
setp_cursor(0,2,62);
pre_time();
setp_cursor(0,2,30);
MYOS3.0"
setp_cursor(0,4,0);
Inputcommand:
setp_cursor(0,5,0);
setp_cursor(0,4,14);
intstrcmp(charstr1[],charstr2[])
intlen1=strlen(str1);
intlen2=strlen(str2);
inti=0,j=0;
while(i<
len1&
&
j<
len2&
str1[i]==str2[j])
i++;
j++;
return(str2[j]-str1[i]);
voidatoA(char*buf)
intlen=strlen(buf);
if('
a'
<
=buf[i]&
buf[i]<
='
z'
)buf[i]
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 8086 汇编 语言 混合 实现 操作系统