一、目的

    知行合一,就是说学以致用。《汇编语言》这本书从13年春节开始看,中间由于众多事物中断,知道14年春节才看完。但是,百看不如一练,借着刚看完书,对汇编语言还很热的感觉,决定对书中最后的课程设计冲刺一下,作为这本书的结业课。

二、课程设计内容

1、题目

阅读下面的材料:

开机后,CPU自动进入到FFFF:0单元处执行,此处有一条跳转指令。CPU执行该指令后,转去执行BIOS中的硬件系统检测和初始化程序。

初始化程序将建立BIOS所支持的中断向量,即将BIOS提供的中断例程的入口地址登记在中断向量表中。

硬件系统检测和初始化完成后,调用int 19h进行操作系统的引导。

如果设为从软盘启动操作系统,则int 19h将主要完成以下工作。

(1)控制0号软驱,读取软盘0道0面1扇区的内容到0:7c00;

(2)将CS:IP指向0:7c00。

软盘的0道0面1扇区中装有操作系统引导程序。int 19h将其装到0:7c00处后,设置CPU从0:7c00开始执行此处的引导程序,操作系统被激活,控制计算机。

如果在0号软驱中没有软盘,或发生软盘I/O错误,则int 19h将主要完成以下工作。

(1)读取硬盘C的0道0面1扇区的内容到0:7c00;

(2)将CS:IP指向0:7c00。

这次课程设计的任务是编写一个可以自行启动的计算机,不需要在现有操作系统环境中运行的程序。

该程序的功能如下:

(1)列出功能选项,让用户通过键盘进行选择,界面如下

1) reset pc          ;重新启动计算机

2) start system      ;引导现有的操作系统

3) clock             ;进入时钟程序

4) set clock         ;设置时间

(2)用户输入"1"后重新启动计算机(提示:考虑ffff:0单元)

(3)用户输入"2"后引导现有的操作系统(提示:考虑硬盘C的0道0面1扇区)。

(4)用户输入"3"后,执行动态显示当前日期、时间的程序。

显示格式如下:年/月/日 时:分:秒

进入此项功能后,一直动态显示当前的时间,在屏幕上将出现时间按秒变化的效果(提示: 循环读取CMOS)。

当按下F1键后,改变显示颜色;按下Esc键后,返回到主选单(提示:利用键盘中断)。

(5)用户输入"4"后可更改当前的日期、时间,更改后返回到主选单(提示:输入字符串)。

2、程序设计思路 

将安装程序分为三个段,

1、第一个段为安装程序,负责将第二个段写入第一扇区,第三个段写入2-11扇区;

2、第二个段是主引导程序,存在于软盘第一扇区,由BIOS的19h中断读取到0:7c00开始的内存单元中,并执行0:7c00的第一行代码。这一段的任务是将软盘2-11扇区的数据读入内存,并执行。(这里读入到了2000h:0h开始的内存中)

3、第三个段是系统程序,存放所有引导所需的程序和子程序

3、程序实现功能

程序实现的功能有:

1) reset pc          ;重新启动计算机

2) start system      ;引导现有的操作系统

3) clock             ;进入时钟程序

4、实现程序

;安装程序代码段
assume cs:code
code segmentstart:    mov ax,initsg ;将初始化代码段写入软盘的第1扇区mov es,axmov bx,0mov al,1mov ch,0mov cl,1mov dl,0mov dh,0mov ah,3int 13hmov ax,mainshell ;将主界面代码段写入软盘的2-11扇区mov es,axmov bx,0mov al,10mov ch,0mov cl,2mov dl,0mov dh,0mov ah,3int 13hmov ax,4c00hint 21h
code ends;初始化代码段
;运行地址:0:7c00h
assume cs:initsg
initsg segment;这部分注释掉的代码为错误代码
;initsgstart: jmp near ptr initstart
;    initsgstack: db 128 dup(0)    ;initstart: ;mov ax,7c0h;mov ss,ax;mov sp,(offset initsgstack)+128initsgstart:    call loadmainshell;将2000h:0h存入堆栈,用retf指令跳转到该处去运行mov ax,2000hpush axmov ax,0push axretf;加载主界面代码段到内存的2000h:0h位置
loadmainshell:    mov ax,2000hmov es,axmov bx,0mov al,10mov ch,0mov cl,2mov dl,0mov dh,0mov ah,2int 13hret
initsg ends;主界面代码段
;运行地址:2000h:0h
assume cs:mainshell
mainshell segment     ;这部分注释掉的代码为错误代码
;mainshellstart:
;    jmp near ptr shellstart
;    mainshellstack: db 128 dup(0)    ;主界面的堆栈区;shellstart:
;        mov ax,cs
;        mov ss,ax
;        mov sp,(offset mainshellstack)+128 ;设置堆栈mainloop:    call menudisplay ;显示主界面call getonechar  ;读取一个字符的输入,al返回输入的字符 mov al,al        ;传递参数call funsecl     ;根据不同的输入执行不同功能的函数jmp short mainloop ;跳到主循环运行;函数功能:根据不同的输入执行不同功能的函数
;函数输入参数:al
funsecl: jmp short funseclectfuntable dw 0,sysrest,sysstart,clockdisplay ;子函数的地址funseclect: push bx;先判断输入的字符是否在允许范围内cmp al,'4'    ja funretcmp al,'1'jb funret;根据不同的输入执行不同功能的函数mov bl,almov bh,0sub bx,'0'add bx,bxcall word ptr funtable[bx]funret: pop bxret;函数功能:系统复位
sysrest:    mov ax,0ffffhpush axmov ax,0push axretf;函数功能:启动操作系统
sysstart: call clearscreencall loadsyskerneladd sp,4    ;为了使跳出本软盘程序时的堆栈和进入本软盘程序开始时的堆栈相同;调整sp+4,因为之前执行了两个call指令,但是都还没有用ret指令返回;将0h:7c00h存入堆栈,用retf指令跳转到该处去运行mov ax,0push axmov ax,7c00hpush axretfloadsyskernel:    ;从硬盘c加载操作系统mov ax,0mov es,axmov bx,7c00hmov al,1mov ch,0mov cl,1mov dl,80hmov dh,0mov ah,2int 13hret ;函数功能:时钟显示,按下ESC键退出显示,按下F1键更改颜色
;参考《汇编语言》280页例程
clockdisplay: jmp short clockstartescflag dw 0     ;是否按下esc键的标志,0:未按下;1:按下int9back dw 0,0    ;保存int9中断向量的空间
clockstart:        push dspush espush bxmov ax,csmov ds,axmov ax,0mov es,ax;备份int9中断向量到int9back中mov bx,offset int9back push es:[9*4]pop ds:[bx]push es:[9*4+2]pop ds:[bx+2];更改int9的中断向量为int9函数地址mov word ptr es:[9*4],offset int9mov es:[9*4+2],cscall clearscreen     ;清屏mov escflag,0       ;将escflag清0mov bx,0b800h        mov es,bx;时钟主循环为不断的更新时间,并显示出来
clockloop:     mov byte ptr es:[160*12+28*2],32hmov byte ptr es:[160*12+29*2],30h    mov al,9call readparamov byte ptr es:[160*12+30*2],ahmov byte ptr es:[160*12+31*2],almov byte ptr es:[160*12+32*2],'/'mov al,8call readparamov byte ptr es:[160*12+33*2],ahmov byte ptr es:[160*12+34*2],almov byte ptr es:[160*12+35*2],'/'mov al,7call readparamov byte ptr es:[160*12+36*2],ahmov byte ptr es:[160*12+37*2],almov byte ptr es:[160*12+38*2],' 'mov al,4call readparamov byte ptr es:[160*12+39*2],ahmov byte ptr es:[160*12+40*2],almov byte ptr es:[160*12+41*2],':'mov al,2call readparamov byte ptr es:[160*12+42*2],ahmov byte ptr es:[160*12+43*2],almov byte ptr es:[160*12+44*2],':'mov al,0call readparamov byte ptr es:[160*12+45*2],ahmov byte ptr es:[160*12+46*2],alcmp escflag,0 ;判断是否按下ESCjne exit      ;如果是,就跳出循环jmp clockloop ;如果不是,继续显示exit:    call clearscreen ;清屏mov ax,0mov es,ax;将原int9中断向量复原mov bx,offset int9backpush ds:[bx]pop es:[9*4]push ds:[bx+2]pop es:[9*4+2]pop bxpop espop dsret;函数功能:读取参数(年、月、日、时、分、秒)
;函数输入参数:al
;函数输出参数:ax
readpara: push cxout 70h,alin al,71hmov ah,almov cl,4shr ah,cland al,00001111badd ah,30hadd al,30hpop cxret;函数功能:按下ESC键更改escflag标志,按下F1键更改颜色
int9:    push axpush bxpush esin al,60hpush axpushfpushfpop bxand bh,11111100bpush bxpopfmov bx,2000hmov ds,bxmov bx,offset int9backcall dword ptr ds:[bx]pop axcmp al,3bhje changecolor     ;按下F1键更改颜色cmp al,01hje quit            ;按下ESC键退出pop espop bxpop axiretchangecolor:    push espush bxmov ax,0b800hmov es,axmov bx,0mov cx,19
changeloop:    inc byte ptr es:[160*12+28*2+1][bx]add bx,2loop changelooppop bxpop esjmp short int9retquit:    mov escflag,1    ;按下ESC键更改escflag标志
int9ret:    pop espop bxpop axiret;函数功能:清屏
clearscreen: push bxpush espush cxmov bx,0b800hmov es,bxmov bx,0mov cx,2000
clearloop:    mov byte ptr es:[bx],' 'mov byte ptr es:[bx+1],07hadd bx,2loop clearlooppop cxpop espop bxret ;函数功能:主界面显示
menudisplay:    jmp short displaytable1: db '1) reset pc',0table2: db '2) start system',0table3: db '3) clock',0table4: db 'Enter your selection:   ',0display:    push dxpush axpush dspush simov dh,10mov dl,30mov ax,csmov ds,axmov si,offset table1call stringsshowmov dh,11mov dl,30mov ax,csmov ds,axmov si,offset table2call stringsshowmov dh,12mov dl,30mov ax,csmov ds,axmov si,offset table3call stringsshowmov dh,13mov dl,30mov ax,csmov ds,axmov si,offset table4call stringsshowpop sipop dspop axpop dxret;函数功能:显示一个字符串
stringsshow:    push bxpush espush axpush dimov bx,0b800hmov es,bxmov al,160mov ah,0mul dhmov di,axadd dl,dlmov dh,0add di,dxmenucharshow:    mov al,ds:[si]cmp al,0je menusret ;如果字符为0,就结束显示mov es:[di],aladd si,1add di,2jmp menucharshowmenusret:    pop dipop axpop espop bxret;子程序:字符栈的入栈、出栈和显示。
;参数说明:(ah)=功能号,0表示入栈,1表示出栈,2表示显示;
;          ds:si指向字符栈空间;
;          对于0号功能:(al)=入栈字符;
;          对于1号功能:(al)=返回的字符;
;          对于2号功能:(dh)、(dl)=字符串在屏幕上显示的行、列位置。charstack:jmp short charstart
table dw charpush,charpop,charshow
top   dw 0          ;栈顶(字符地址、个数记录器)charstart:push bxpush dxpush dipush escmp ah,2      ;判断ah中的功能号是否大于2ja sret            ;功能号>2,结束mov bl,ahmov bh,0add bx,bx     ;计算对应子程序在table表中的偏移jmp word ptr table[bx] ;调用对应的功能子程序 charpush:mov bx,topmov [si][bx],alinc topjmp sretcharpop:cmp top,0je sret            ;栈顶为0(无字符),结束dec topmov bx,top         ;//保存数据,其它作用不详mov al,[si][bx]        ;//保存数据,其它作用不详jmp sret  charshow:mov bx,0b800hmov es,bxmov al,160mov ah,0mul dh             ;dh*160mov di,axadd dl,dl     ;dl*2mov dh,0add di,dx     ;di=dh*160+dl*2,es:di指向显存mov bx,0      ;ds:[si+bx]指向字符串首地址charshows:cmp bx,top        ;判断字符栈中字符是否全部显示完毕jne noempty        ;top≠bx,有未显示字符,执行显示mov byte ptr es:[di],' ';显示完毕,字符串末加空格jmp sretnoempty:mov al,[si][bx]     ;字符ASCII码赋值almov es:[di],al         ;显示字符mov byte ptr es:[di+2],' '  ;字符串末加空格inc bx             ;指向下一个字符add di,2      ;指向下一显存单元jmp charshowssret:    pop espop dipop dxpop bxret;子程序:读取一个字符的输入
;读取到的输入:al    getonechar:   jmp short getonecharstartchar db 8 dup(0) ;存输入的位置
getonecharstart: push dspush sipush dxmov char,0 ;输入存储单元清零mov top,0  ;将输入计数器清零mov ax,csmov ds,axmov si,offset char;输入显示的位置是13行52列mov dh,13mov dl,52call getstrmov al,charpop dxpop sipop dsretgetstr:  push ax
getstrs:mov ah,0int 16hcmp al,20hjb nochar     ;ASCII码小于20h,说明不是字符 cmp top,0     jne getstrs  ;如果有一个输入,就等待Enter键按下结束输入或者Backspace键删除;如果没有输入,就将这个输入的字符保存起来mov ah,0call charstack         ;字符入栈mov ah,2call charstack         ;显示栈中字符jmp getstrsnochar:  cmp ah,0eh         ;退格键的扫描码je backspacecmp ah,1ch             ;Enter键的扫描码je enterjmp getstrsbackspace:mov ah,1call charstack         ;字符出栈mov ah,2call charstack         ;显示栈中字符jmp getstrsenter:   mov al,0mov ah,0call charstack         ;0入栈mov ah,2call charstack         ;显示栈中字符pop axretmainshell ends
end start

code

3、测试方法

软件介绍:

  仿真虚拟软驱(点击下载):运行在windows上,像真实的软驱一样可以支持虚拟镜像的读写

  vFloppy 1.5(点击下载):脱离与windows运行,其镜像可以像真实软盘那样在PC启动时运行

(1)虚拟机+虚拟软驱镜像(vfloppy.img)

测试使用工具:VMware虚拟机、仿真虚拟软驱

a)安装仿真虚拟软驱,并加载镜像(vfloppy.img)后,“我的电脑”中会模拟出一个“3.5 软盘 (A:)”,可以像真的软盘一样对其进行读写等。

说明:虚拟软驱就相当于物理软驱,虚拟镜像就相当于软盘,加载镜像就相当于将软盘插入软驱


b)在windows命令行下对程序进行编译、连接,执行后引导代码写入到软盘中

说明:写入软盘实际上就是写入虚拟镜像(vfloppy.img)
c)首先卸载虚拟镜像(vfloppy.img),然后新建一个虚拟机,使用虚拟镜像(vfloppy.img)引导,启动虚拟机。

说明:卸载虚拟镜像的目的是因为,虚拟光驱占用着vfloppy.img时,虚拟机就不能使用这个文件了。

d) 虚拟机上的运行效果

(2)物理机+虚拟软驱镜像(vfloppy.img)(实机操作,慎用)

测试使用工具:物理机、仿真虚拟软驱、vFloppy 1.5

a) 制作vfloppy.img方法同方式(1)的前两个步骤一样

b) 使用vFloppy 1.5制作“启动软盘”

c) 选择刚才制作好的虚拟镜像vfloppy.img,然后点击“应用”。

此时,可以查看c盘隐藏的系统文件boot.ini相应发生的改变。

d)重启就可以看到启动菜单(显示文本)。选择从“显示文本”项启动,就可以看到vfloppy中程序的运行效果。

 三、调试过程中遇到的问题及解决方法

1、代码的位置无关性

(1)概念

 位置有关性代码:

  它的链接地址在编译的时候已经确定,也就是说将来运行时候要将这部分代码搬移到指定的位置(链接位置)才能正确运行。例如:

;段代码功能:sum单元加1asscume cs:codecode segmentsum dw 0start:mov ax,2000hmov ds,axinc word ptr ds:[0]mov ax,4c00hint 21hcode ends
end start

如果要实现sum单元加1,就必须使代码加载到2000h:0的位置才能正确执行。

 位置无关性代码:

  这些代码放在任何位置都能正确运行,与链接地址无关。例如相对跳转指令,jmp short 标号。还是上边的程序,稍作修改就变成位置无关代码了。

;段代码功能:sum单元加1
assume cs:codecode segmentsum dw 0start:mov ax,cs           ;把2000h换成csmov ds,axinc word ptr ds:[0]mov ax,4c00hint 21hcode ends
end start

  实际上,这个程序还不是完美的位置无关代码,在更改CS的情况下,能正确执行。但是在变更IP的情况下,还会出错。

(2)我的结论

  X86架构的指令在设计的时候,即是位置有关的,也是位置无关的。CS是位置无关的,IP是位置有关的。

解释CS的位置无关性

  假设程序段中没有使用跨段跳转指令和含绝对段地址的指令,再假设程序链接地址是2000h:0h,实际运行地址是7c0h:0h,程序是能正常运行的。因为内部的指令的链接地址都是相对于段首(段首IP为0)而来,当运行的时候,我们的指令只更改IP,不更改CS,自然能够正确运行。

解释IP的位置有关性

  一个代码段,在链接时候,连接地址都是相对于段首(IP为0)。假设程序链接地址是2000h:0h,而程序被加载到了0:7c00h处去执行。也就是说,链接的时候IP的首址为0,执行的时候是7c00h。程序就不能正确执行。举例说明。测试程序还是上边的代码为:

;段代码功能:sum单元加1
assume cs:codecode segmentsum dw 0start:mov ax,cs           ;把2000h换成csmov ds,axinc word ptr ds:[0]mov ax,4c00hint 21hcode ends
end start

sum单元的地址是程序加载的物理地址偏移量为0。程序被加载到0h:7c00h处去执行,所以sum单元的物理地址是7c00h。但是,我们看程序中sum的访问地址ds:[0],程序执行后是0h:0h。这显然不是我们想要的sum位置。

解释真正的位置无关代码

真正意义上的位置无关代码,不受IP的限制(CS的位置无关性),放在何处运行都正确。例如下边的程序:

 ;段代码功能:sum单元加1
assume cs:codesg
codesg segmentsum dw 0
codesgstart:call getip ;获得下一条指令的运行地址
pos:           mov bx,axmov ax,offset pos sub bx,ax    ;获得sum的真实物理地址mov ax,cs          mov ds,axinc word ptr ds:[bx]mov ax,4c00hint 21h;========================================================
;函数功能:获得当前的IP,也即下一条指令的地址
;函数返回:ax
;========================================================
getip:push bxmov ax,ssmov ds,axmov bx,spmov ax,ds:[bx+2]pop bxret

如果想测试这段代码,请看详细版本的代码:

;========================================================
;段代码功能:加载codesg段到2000h:7f00h位置处,并且将cs:ip
;设定到2000h:7f02处去执行,以测试codesg段是否是真正意义的
;位置无关代码
;========================================================
assume cs:setupsg,ss:stack
stack segmentdb 128 dup(0)
stack endssetupsg segment
start:mov ax,stackmov ss,axmov sp,128mov ax,codesgmov ds,axmov si,0 ;设置ds:si指向源地址mov ax,2000hmov es,axmov di,7f00h ;设置es:di指向目标地址mov cx,offset codesgend-offset codesgstart+2cldrep movsbmov ax,2000hpush axmov ax,7f02h ;codesg段的第一条地址是偏移量为2的地方push axretfsetupsg ends ;========================================================
;段代码功能:sum单元加1
;========================================================
assume cs:codesg
codesg segmentsum dw 0
codesgstart:call getip ;获得下一条指令的运行地址
pos:           mov bx,axmov ax,offset pos sub bx,ax    ;获得sum的真实物理地址mov ax,cs          mov ds,axinc word ptr ds:[bx]mov ax,4c00hint 21h;========================================================
;函数功能:获得当前的IP,也即下一条指令的地址
;函数返回:ax
;========================================================
getip:push bxmov ax,ssmov ds,axmov bx,spmov ax,ds:[bx+2]pop bxretcodesgend:nop
codesg ends
end start

View Code

(3)本课程设计程序中遇到的位置有关代码问题

程序一开始没有mainshell段,这部分代码紧随initsg段。编译好后,被写入到了虚拟镜像。等于说是,虚拟镜像上的程序就只有一个代码段。开机时,虚拟镜像的程序被加载到了0h:7c00h出去执行。但是initsg段在编译后的段首址的IP值为0。程序不能正常运行。

解决办法就是设置两个段,一个是mainshell段,是真正的代码段,这个段含有位置有关代码,必须放在IP为0的位置处运行。一个是initsg段,负责将mainshelll段搬运到2000h:0h处,并且设置cs:ip到该处去运行,这个段是位置无关代码。

(4)如何设计位置无关代码的程序

位置无关代码的程序必须不能使用绝对地址,而要使用相对地址。相对跳转就是为设计位置无关代码来服务的。

我认为,x86汇编指令用cs:ip这样的指令指针(pc)方式,引入代码段的概念,也就是为设计位置无关代码考虑的。

2、中断程序不能随意返回

中断返回的地址不能随意更改,必须是从哪里断的返回到哪里。

因为,假设从调用了n次“call 标号”后的子程序中断的,而更改了返回地址跳到别处去。这个时候,即使中断程序写的很好,保证了进入和出去中断时sp的不变(堆栈的不变)。但是,由于返回的不是原断点处,就有很大的可能堆栈不能完全恢复(因为还需要n次ret指令来恢复中断),导致错误。

3、堆栈设置问题

这个课程设计程序的堆栈是不需要我们来设置的,因为BIOS在启动的时候已经设置过了。倘若,我们重新指定堆栈的位置,就有可能导致错乱。

堆栈的使用必须小心,保证进出函数时堆栈的不变。因为堆栈里边存放了寄存器的值,变量的值,还有返回地址,所以必须小心。

参考资料:王爽汇编语言课程设计2

转载于:https://www.cnblogs.com/amanlikethis/p/3566133.html

《汇编语言》课程设计相关推荐

  1. C++《面向对象程序设计课程设计》

    C++<面向对象程序设计课程设计> <面向对象程序设计课程设计>课程说明 适用专业:计算机科学与技术 课程周数:5周 一.根据计算机科学与技术专业人才培养方案制订. (一)课程 ...

  2. 面向对象程序设计课程设计:利用决策树方法判定西瓜质量

    目录 第一章课程设计的目的及要求 1.1课程设计目标 1.2课程设计实验环境 1.3课程设计的预备知识 1.4课程设计要求 第二章课程设计的内容 2.1c++语言程序设计--<利用决策树方法判定 ...

  3. 武汉工程大学信息与计算科学专业面向对象程序设计课程设计题

    课程设计内容(从以下任务中任选一个) 1  售票处的服务系统 设计民航售票处的计算机系统可以为客户提供以下各项服务: (1)查询航线:根据旅客提出的终点站名输出以下信息:航班号.飞机号.星期几飞行.最 ...

  4. c++面向对象程序设计------课程设计

    课程设计要求 本次考试可以选择使用的理论知识点罗列如下: 常量.new/delete.引用.构造函数.析构函数.拷贝构造.静态成员.友元.组合类.重载函数.虚函数.运算符重载.模板.错误异常处理.格式 ...

  5. 面向对象程序设计课程设计——MFC实现同学通讯录管理系统

    先上效果图; 1.设计目的 同学通讯录管理程序是为了更好地管理学生信息而开发的数据管理软件.如今,同学与同学.老师与同学联系都是通过电话联系.但是,通常这些数据与其他人的信息混合在一起,同学信息并不方 ...

  6. 程序设计课程设计报告(学生成绩管理系统)

    程序设计课程设计报告 课程设计题目及内容 题目:学生成绩管理系统 设计要求及提示如下: (1).设计一个学生类Student,包括数据成员:姓名.学号.二门课程(面向对象程序设计.高等数学)的成绩. ...

  7. C#面向对象程序设计课程实验二: 实验名称:Windows 窗体程序

    C#面向对象程序设计课程实验二: 实验名称:Windows 窗体程序 实验内容:Windows 窗体程序 一.实验目的及要求 二.实验环境 三.实验内容与步骤 一.设计简单的计算器 3.1.实验内容 ...

  8. C#面向对象程序设计课程实验一:实验名称:C#语言基础、程序流程控制

    C#面向对象程序设计课程实验一:实验名称:C#语言基础.程序流程控制 实验内容:C#语言基础.程序流程控制 一. 实验目的 二.实验环境 三.实验内容 四.实验总结 实验内容:C#语言基础.程序流程控 ...

  9. 猜数字java程序设计分析_JAVA程序设计课程设计-猜数字游戏设计

    JAVA程序设计课程设计-猜数字游戏设计 课 程 设 计 报 告课程设计名称 Java 程序设计 专 业 计算机科学与技术 班 级 2 班 学 号 08030212 姓 名 指导教师 成 绩 2011 ...

  10. java猜数字游戏课程设计报告_Java程序设计课程设计-猜数字游戏设计.doc

    Java程序设计课程设计-猜数字游戏设计.doc 还剩 23页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,喜欢就下载吧,价低环保! 内容要点: 课 程 设 计 报 告课程设计名称 Jav ...

最新文章

  1. inshot怎么转gif_Figma插件开发-生成Gif
  2. python控制台输出颜色
  3. 用友为什么要进军PLM市场
  4. 制作类似QQ截图软件
  5. 使用百度云服务器BCC搭建网站,过程记录
  6. 攻破 程序员35岁 “瓶颈” 那都不是事!
  7. 2018/7/9-纪中某B组题【jzoj1503,jzoj1158,jzoj1161】
  8. 【稀疏向量技术是什么?】差分隐私系统学习记录(六)
  9. 解决安卓TextView高度和textSize大小不一致问题
  10. 【渝粤教育】广东开放大学 民族音乐概论 形成性考核 (58)
  11. 【wikioi】1014 装箱问题
  12. 基于钉钉服务简单监控
  13. Nginx反向代理、静态资源下载
  14. 测试计划模板——Test Plan(中英文)
  15. UML及UML建模工具介绍
  16. linux开机自检时间长,Linux 开机自检的设置(tune2fs和fsck)
  17. Html漂亮的table样式模板
  18. IIC协议之SHT30温湿度采样
  19. c++读取MP3文件专辑图片、歌手名等ID3v2信息
  20. 联想x3650服务器安装硬盘,IBM x3650 M2服务器系统安装攻略(组图)

热门文章

  1. LQR轨迹跟踪算法Python算法实现3
  2. mysql不对称复制数据_mysql UNION all 实现不对称数据统计
  3. android 字符串转浮点,Android String类型转换为float、double和int的工具类方法
  4. 漫步VR——Unity语音聊天室开发小结
  5. java代码嵌入html代码是什么_用java给html文件添加必要的控制html代码片
  6. Java基础---接口的使用
  7. 图书馆管理系统项目思路
  8. nginx 4层代理配置
  9. js获取当前时区GMT
  10. HTMLCSS常见问题整理(四)