📌 汇编语言是很多相关课程(如数据结构、操作系统、微机原理)的重要基础。但仅仅从课程的角度出发就太片面了,其实学习汇编语言可以深入理解计算机底层工作原理,提升代码效率,尤其在嵌入式系统和性能优化方面有重要作用。此外,它在逆向工程和安全领域不可或缺,帮助分析软件运行机制并增强漏洞修复能力。 本专栏的汇编语言学习章节主要是依据王爽老师的《汇编语言》来写的,和书中一样为了使学习的过程容易展开,我们采用以8086CPU为中央处理器的PC机来进行学习。
在系统板的ROM中存放着一套程序,称为BIOS(基本输入输出系统),BIOS中主要包含以下几部分内容。
操作系统DOS也提供了中断例程,从操作系统的角度来看,DOS的中断例程就是操作系统向程序员提供的编程资源。
BIOS和DOS在所提供的中断例程中包含了许多子程序,这些子程序实现了程序员在编程的时候经常需要用到的功能。程序员在编程的时候,可以用int指令直接调用BIOS和 DOS 提供的中断例程,来完成某些工作。
和硬件设备相关的 DOS 中断例程中,一般都调用了BIOS的中断例程。
前面的课程中,我们都是自己编写中断例程,将它们放到安装程序中,然后运行安装程序,将它们安装到指定的内存区中。此后,别的应用程序才可以调用。
而BIOS和DOS提供的中断例程是如何安装到内存中的呢?
我们下面讲解它们的安装过程:
下面我们举几个例子,来看一下BIOS中断例程的应用。
int 10h中断例程是BIOS提供的中断例程,其中包含了多个和屏幕输出相关的子程序。
一般来说,一个供程序员调用的中断例程中往往包括多个子程序,中断例程内部用传递进来的参数来决定执行哪个子程序。
BIOS 和DOS 提供的中断例程,都用ah来传递内部子程序的编号。
下面看一下int 10h中断例程的设置光标位置功能。
mov ah,2 ;置光标
mov bh,0 ;第0页
mov dh,5 ;dh中放行号
mov dl,12 ;dl中放列号
int 10h
(ah)=2表示调用第 10h 号中断例程的 2号子程序。
功能为设置光标位置,可以提供光标所在的行号(80*25字符模式下:0~24)、列号(80*25字符模式下:0~79),和页号作为参数。
(bh)=0,(dh)=5,(dl)=12,设置光标到第0页,第5行,第12列。
bh中页号的含义:内存地址空间中,B8000H~BFFFFH共32kB的空间,为80*25彩色字符模式的显示缓冲区。
一屏的内容在显示缓冲区中共占4000个字节。
显示缓冲区分为8页,每页4KB(≈4000B),显示器可以显示任意一页的内容。一般情况下,显示第0页的内容。也就是说,通常情况下,B8000H~B8F9FH中的4000个字节的内容将出现在显示器上。
再看一下int 10h中断例程的在光标位置显示字符功能。
mov ah,9 ;在光标位置显示字符
mov al,‘a’ ;字符
mov bl,7 ;颜色属性
mov bh,0 ;第0页
mov cx,3 ;字符重复个数
int 10h
(ah)=9 表示调用第10h号中断例程的9号子程序;
功能为在光标位置显示字符,可以提供要显示的字符、颜色属性、页号、字符重复个数作为参数。
(bh)中的颜色属性格式如下:
可以看出,和显存中的属性字节的格式相同。
编程:在屏幕的5行12列显示3个红底高亮闪烁绿色的‘a’。
assume cs:code
code segment
mov ah,2 ;置光标
mov bh,0 ;第0页
mov dh,5 ;dh中放行号
mov dl,12 ;dl中放列号
int 10h
mov ah,9 ;置光标
mov al,'a' ;字符
mov bl,11001010b ;颜色属性
mov bh,0 ;第0页
mov cx,3 ;字符重复个数
int 10h
mov ax,4c00h
int 21h
code ends
end
int 21h 中断例程是DOS提供的中断例程,其中包含了DOS提供给程序员在编程时调用的子程序。
我们以前一直使用的是 int 21中断例程的 4ch号功能,即程序返回功能,如下:
mov ah,4ch ;程序返回
mov al,0 ;返回值
int 21h
(ah)=4ch表示调用第21h号中断例程的 4ch 号子程序,功能为程序返回,可以提供返回值作为参数。
我们前面使用这个功能的时候经常写做:
mov ax,4c00h
int 21h
我们看一下int 21h中断例程的在光标位置显示字符串的功能:
ds:dx指向字符串 ;要显示的字符串需用“$”作为结束符
mov ah,9 ;功能号9,表示在光标位置显示字符串
int 21h
(ah)=9表示调用第21h号中断例程的9号子程序,功能为在光标位置显示字符串,可以提供要显示字符串的地址作为参数。
编程:在屏幕的5列12行显示字符串“Welcome to masm! ”。
程序如下:
assume cs:code
data segment
db 'Welcome to masm!','$'
data ends
code segment
start:
mov ah,2 ;置光标
mov bh,0 ;第0页
mov dh,5 ;dh中放行号
mov dl,20 ;dl中放列号
int 10h
mov ax,data
mov ds,ax
mov dx,0 ;ds:dx指向字符串的首地址data:0
mov ah,9
int 21h
mov ax,4c00h
int 21h
code ends
end start
上述程序在屏幕的5列12行显示字符串“Welcome to masm! ”,直到遇见“”(“” 本身并不显示,只起到边界的作用)。
如果字符串比较长,遇到行尾,程序会自动转到下一行开头处继续显示;如果到了最后一行,还能自动上卷一行。
DOS为程序员提供了许多可以调用的子程序,都包含在 int 21h 中断例程中。
我们这里只对原理进行了讲解,对于DOS提供的所有可调用子程序的情况,读者可以参考相关的书籍。
今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。
也可以点点关注,避免以后找不到我哦!
Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!