汇编语言:课程设计2

前言

由于本人水平不够,这里的课程设计2的程序实现并没有像王爽书中所说的那样可以不依赖于操作系统运行。
这里的程序依然要在dos下运行,而且没有实现引导现有操作系统的功能。
该程序的功能如下:
1) reset pc ;重新启动计算机
2) clock ;进入时钟程序
3) set clock ;设置时间
4) exit ;退出程序

说明:
(1)用户按下“1”后重新启动计算机
(2)用户按下“2”后,执行动态显示当前日期、时间的程序。显示格式:年/月/日 时:分:秒
进入此功能后,一直动态显示当前时间,在屏幕上将出现时间按秒变化的效果(循环读取CMOS)
当按下F1至F7键后,显示不同的文字颜色。按下Esc键后,返回主菜单。
(3)用户按下“3”后可更改当前的日期、时间,更改后返回主菜单。
(4)用户按下“4”后,退出程序。

遗憾

实际编程的过程中,功能3——修改当前时间没有完成,虽然代码中也加入了写入71h端口的指令,但是没有卵用,读取CMOS依旧是原来的时间。
这个程序原来功能2中修改显示颜色的功能原本是想只按F1键,依次切换7种颜色的,但是调试时发现问题(颜色的显示简直是随机的!!),后来才改成F1~F7键,按一个键,换一种颜色。
最大的遗憾就是没有实现在裸机上跑。我对什么软盘映像文件,引导,虚拟机是很头疼的(好吧,我承认就是我比较菜,而且还懒得自学)

实现

其实代码比较垃圾,只是贴出来纪念一下。

其中的重启计算机的指令可以这么写:

mov     ax,0ffffh
push ax
mov ax,0
push ax
retf

这就是对retf指令的灵活运用!而我却没有想到,即使我能轻松读懂这段指令。我的做法是:在数据段保存跳转地址,用jmp指令实现。
关于int 16h中断例程,我用了0号功能,从BIOS键盘缓冲区中取出ASCII码(或扫描码),这里我就不详细介绍了。简单来说,int 9中断例程是向键盘缓冲区写入数据(可以从60h端口读出扫描码),int 16h中断例程就是从键盘缓冲区读出数据。

功能3中,我参考书中的字符串输入的程序,自己实现了一个只适用于功能3的日期时间输入子程序。这里要简单介绍一下字符串输入的实现思想。不同于高级语言,汇编的世界里字符串输入是要自己实现的。
字符串的输入有下面的要求:

  • 输入的同时显示字符串(有回显)
  • 输入回车符后,字符串输入结束(回车键释放缓冲区)
  • 退格键删除已经输入的字符

这里要用到“栈”这一简单的数据结构,编程思路如下:

  1. 调用int 16h读取键盘输入
  2. 如果是字符,进入字符栈,显示字符栈中所有字符,再转到步骤1
  3. 如果是退格键,从字符栈中弹出一个字符,显示字符栈中所有字符,再转到步骤1
  4. 如果是Enter键,结束输入过程

代码清单如下:

assume  cs:code,ds:data
data segment
dw 0,0ffffh ;4byte(offset:0~3)
db '1) reset pc '
db '2) clock '
db '3) set clock '
db '4) exit ' ;64byte(offset:4~67)
time db '00/00/00 00:00:00' ;17byte(offset:52~68)
list db 9,8,7,4,2,0 ;
pos dw 0,1,3,4,6,7,9,10,12,13,15,16
des dw 0,2,6,8,12,14,18,20,24,26,30,32
top dw 0 ;top变量的范围:0~24
data ends ;top变量的作用:确定数字在屏幕上的位置des,
; 确定缓冲区中数据的位置pos
code segment
main: call clear
call menu
s: mov ah,0
int 16h cmp al,'1'
je do1
cmp al,'2'
je do2
cmp al,'3'
je do3
cmp al,'4'
je exit
jmp s do1: call reset_pc do2: call clear
call clock
jmp main
do3: call set_clock
jmp main exit: mov ax,4c00h
int 21h
;------------------------------------------
;子程序:clear
;功能:清屏
clear: push bx
push es mov bx,0b800h
mov es,bx
mov bx,0
cls: mov byte ptr es:[bx],' '
add bx,2
cmp bx,2000
jb cls pop es
pop bx
ret
;------------------------------------------
;子程序:set_color
;功能:设置显示颜色
;入口参数: (al) = 颜色值(0~7)
set_color: push bx
push es mov bx,0b800h
mov es,bx
mov bx,1
set_color_s: mov es:[bx],al
add bx,2
cmp bx,2000
jb set_color_s pop es
pop bx
ret
;------------------------------------------
;子程序:menu
;功能:在屏幕上显示菜单选项
menu: push ax
push cx
push si
push di
push es mov ax,data
mov ds,ax
mov ax,0b800h
mov es,ax mov si,4
mov di,160*5+30*2
mov cx,4
menu_s : push cx
mov cx,16
menu_s1: mov al,[si]
mov es:[di],al
inc si
add di,2
loop menu_s1
add di,160-16*2
pop cx
loop menu_s pop es
pop di
pop si
pop cx
pop ax
ret
;------------------------------------------
;子程序:reset_pc
;功能: 重启计算机
reset_pc: mov ax,data
mov ds,ax
jmp dword ptr ds:[0]
;------------------------------------------
;子程序:clock
;功能: 动态显示当前时间
clock: push ax
push bx
push cx
push si
push di
push es mov bx,0b800h
mov es,bx mov bx,0
mov di,160*5+30*2
clock_init: mov al,time[bx]
mov byte ptr es:[di],al
inc bx
add di,2
cmp bx,17
jb clock_init show_time: mov di,160*5+30*2
mov bx,0
mov cx,6
show_s: push cx
mov al,list[bx]
out 70h,al
in al,71h
mov ah,al
mov cl,4
shr al,cl
and ah,00001111b
add ax,3030h mov es:[di],al
mov es:[di+2],ah
add di,3*2
inc bx
pop cx
loop show_s in al,60h
cmp al,1 ;按下Esc键返回主菜单
je clock_ret
cmp al,3bh
jb show_time ;按下F1~F7键更改显示颜色
cmp al,41h
ja show_time
;更改显示颜色
change: sub al,3ah
call set_color
jmp short show_time clock_ret: mov al,7
call set_color pop es
pop di
pop si
pop cx
pop bx
pop ax
ret
;------------------------------------------
;子程序:set_clock
;功能: 修改当前时间
set_clock: jmp short set_start
set_time db '00/00/00 00:00:00'
set_start: push ax
push bx
push cx
push si
push di
push es call clear
mov bx,0b800h
mov es,bx
mov bx,0
mov di,160*5+30*2
set_init: mov al,set_time[bx]
mov es:[di],al
add di,2
inc bx
cmp bx,17
jb set_init call gettime mov si,0
mov bx,0
cset: mov al,list[si]
out 70h,al
mov di,des[bx]
mov ah,es:[160*5+30*2+di]
sub ah,'0'
mov cl,4
shl ah,cl
mov al,es:[160*5+30*2+2+di]
sub al,'0'
add al,ah
out 71h,al
add bx,2*2
inc si
cmp si,6
jb cset pop es
pop di
pop si
pop cx
pop bx
pop ax
ret
;-------------------------------------------
;子程序:gettime
;功能:输入时间
gettime: push ax gets: mov ah,0
int 16h
cmp al,'0'
jb nodigit
cmp al,'9'
ja nodigit
mov ah,0
call charstack
mov ah,2
call charstack
jmp gets nodigit: cmp ah,0eh
je backspace
cmp ah,1ch
je _enter
jmp gets backspace: mov ah,1
call charstack
mov ah,2
call charstack
jmp gets _enter: mov ah,2
call charstack pop ax
ret
;-------------------------------------------
;子程序:charstack
;入口参数:
;(ah) = 功能号, 0表示入栈, 1表示出栈,2表示显示
;对于功能0: (al) = 入栈字符
charstack: jmp short charstart
table dw charpush,charpop,charshow
charstart: push ax
push bx
push si
push di
push es cmp ah,2
ja chret
mov bl,ah
mov bh,0
add bx,bx
jmp word ptr table[bx] charpush: cmp top,24 ;边界情况处理
je chret
mov bx,top
mov si,pos[bx]
mov time[si],al
add top,2
jmp chret charpop: cmp top,0 ;边界情况处理
je chret
sub top,2
jmp chret charshow: mov bx,0b800h
mov es,bx
mov di,0
mov bx,0 charshows: mov si,pos[bx]
cmp bx,top
jne noempty
cmp bx,24 ;边界情况处理,确保数字屏显正常
je chret
mov byte ptr es:[160*5+30*2+di],'0'
jmp chret
noempty: mov al,time[si]
mov es:[160*5+30*2+di],al
add bx,2
mov di,des[bx]
jmp charshows chret: pop es
pop di
pop si
pop bx
pop ax
ret
;------------------------------------------
code ends
end main

演示画面

菜单页面

重启电脑

时间显示(绿色)

结束语

第一阶段汇编语言的自学到这里就告一段落了,虽然留下了不少遗憾,但也有不少收获。这次课程设计是我最后的汇编程序了,有一些功能没有实现,以后我也不准备弥补了。这就好像所有的期末(升学)考试一样,即使考得再差,也不会有老师在考完后评讲试卷,不会有学生修改错题。这次课程设计的源程序不久就会被删除(垃圾总是要清理的,笑),接下来我要复习C语言,应付来年的计算机二级考试。
第二阶段的汇编语言学习,我已经有了初步的计划,参考书是《x86汇编语言——从实模式到保护模式》。什么时候开始新阶段的学习呢?看我心情吧。(也可能转变学习方向,学习AT&T格式的汇编)

See You Again——我最后的汇编程序的更多相关文章

  1. x86汇编程序基础(AT&T语法)

    一.简单的汇编程序 以下面这段简单的汇编代码为例 .section .data .section .text .globl _start _start: movl $, %eax movl $, %e ...

  2. ARM汇编程序结构

    ARM汇编程序结构 一个ARM程序可以被划分为多个代码段和数据段,在汇编的时候这些段会被形成一个可执行文件 .text ;正文段,包含程序的指令代码 .data ;数据段,包含固定的数据,如常量,字符 ...

  3. VS2012下X64平台嵌入汇编程序

    VS2012在win32平台编译的时候可以很好的支持汇编语言的嵌入.建立一个控制台应用程序,选择空项目.项目建立好之后添加一个.cpp文件.在cpp文件中写入如下代码: #include <io ...

  4. 汇编程序的Hello world

    原文链接:http://www.orlion.ga/989/ 一.汇编程序的Hello world x86 AT&T: .data   msg:       .ascii "Hell ...

  5. ARM汇编程序基本知识

    ARM汇编程序基本知识 1.汇编程序的基本组成 ARM汇编语言程序中,程序是以程序段为单位组织代码的.段是相对独立的指令或者代码序列,拥有特定的名称.段的种类有代码段.数据段和通用段,代 码段的内容为 ...

  6. 使用Visual Studio 2013 调试 MASM 汇编程序!

    原文地址:http://kipirvine.com/asm/debug/vstudio2013/index.htm Using the Microsoft Visual Studio 2013 Deb ...

  7. TC2.0中怎样调用汇编程序

    转载于: TC2.0中怎样调用汇编程序 一.概述 TC是美国BORLAND 公司在IBM PC机上开发的一个高效.优化的C编译程序,它自带高效的全屏幕编辑程序,在集成开发环境下可支持编辑.编译.连接调 ...

  8. 如何用Visual Studio 2008 写汇编程序?

    如何用Visual Studio 2008写汇编程序? 最近在上夏季小学期,在学汇编语言,关于用什么编辑环境一直很纠结.很想找到一个比较好的IDE,但是试了几个像RadASM之类的,发现还不是很满意. ...

  9. 架设WIN32汇编程序的开发环境

    笔者在学习Windows下的图形界面应用程序(GUI,Graphical User Interface)的时候碰到的第一个麻烦就是架设WIN32汇编程序的开发环境,在这里笔者愿意和大家分享这段经历. ...

  10. DOS下读取spd信息的汇编程序(通过SMBus)

    汇编程序编写的读取spd信息的代码: ;----------------------------------------------------------- ;功能: 通过SMbus 读取内存的SP ...

随机推荐

  1. ZT自贴吧 说说你是怎么和恋人确定恋爱关系的?

    http://www.baidu.com/link?url=svJFMqibXXhJUiGDaDr1obOyrIb9o0TqO5JWFtMuM-l7ndaRlGMyuRQKCOHh-Pj0

  2. ego network的概念

    转:http://greatpowerlaw.wordpress.com/2013/01/05/ego-network/ 所谓的ego network,它的节点是由唯一的一个中心节点(ego),以及这 ...

  3. NPM cache相关

    今天下午把package.lock.json用别人的替换了,然后编译一堆报错,这个问题弄了一下午. 总结一下经验: 1.关于npm cache NPM会把所有下载的包保存,放在用户文件夹下面,在我的w ...

  4. redis持久化那些事(kēng)儿

    这是一篇包含了介绍性质和吐槽性质的日志.主要介绍一下我学习redis持久化时候被坑的经历.redis的使用介绍现在没有打算写,因为比较多,以我如此懒的性格...好吧,还是有点这方面想法的,不过一篇博客 ...

  5. Perl中的字符串操作函数

    1.$position = index(string,substring,skipchars): 该函数返回子串substring在字符串string中的位置,如果不存在,则返回-1:参数skipch ...

  6. 20145223 杨梦云 《网络对抗》shellcode实验+return-to-libc实验

    20145223 杨梦云 <网络对抗>shellcode实验+return-to-libc实验 shellcode注入实践 Shellcode基础知识 ·Shellcode实际是一段代码( ...

  7. Selenium基础知识(元素定位的调试)

    对一个不能直接定位的元素来说,调试是很常见的事,所以这里也简单总结了一下. 调试定位元素的工具很多,介绍也多,就不一一介绍了.下次有时间再补充.以下是我常用调试的方法(浏览器自带的控制台调试,仅介绍一 ...

  8. 装饰模式案列(OutputStream)

    使用装饰模式进行装饰OutputStream 写入文件成功 装饰类继承OutputStream类 DecorOutputStream package com.wbg.springRedis.decor ...

  9. Lua库-bit32库

    Global = Global or {}; local bits = {}; function bits.bxor(num1,num2) local ret=bit32.bxor(num1,num2 ...

  10. 用模板引擎Art-Template渲染空格或换行符引发的一场“命案”

    一.绪论 说实话,真的不知道如何给这篇博客命名,因为我觉得应该有一些小伙伴遇到跟我同样的问题正在抓耳挠腮中. 二.导火索 最近在做一个移动H5翻页的功能,类似于MAKA模板那种.假设大致框架如下 ​ ...