0%

HIT_OS 课程下的汇编笔记

此文用来记录在进行 HIT_OS 课程时,遇到的一些跟汇编语言相关的问题(纯汇编小白角度)。

注意:以下内容都是 x86 机器下的汇编知识。

entry

entry是汇编语言中的伪指令,告诉 cpu 这段汇编程序的入口是什么,一般而言,后面跟的就是汇编程序入口。

mov

mov是数据传送指令,也是最基本的汇编编程指令,用于将一个数据从源地址传送到目标地址(寄存器之间的数据传送本质上也是一样),其特点是不破坏源地址单元的内容(属于复制性质,不属于搬家性质),基本用法:

1
2
3
!   mov dst,src
mov EAX,#050aH ;将十六进制数 050a 传送到通用寄存器 EAX 中
mov DI,BX ;寄存器之间传数

注意 mov 的两个操作数不能同时为段寄存器,其他注意事项等内容参考百度百科:MOV

xor

这个没啥说的,异或操作,C 语言中出现过的东西。不过在汇编这里好像用的很多?

ax ah al

ax 是 cpu 内部一个寄存器助记符,通常称之为累加器。以这门课上的 16 位 cpu 为例,ah(a high) 就是 ax 的高八位,al(a low) 就是 ax 的低八位。通俗来讲,若 ax=1234h,那么 ah=12h,al=34h。对应的,其他寄存器一样也有与其对应的 h 和 l。

int

int 应该是汇编中专门用来调用中断的一个指令,后面跟的就是各种各样的“中断码”,不同的“中断码”实现的功能不一样。

基地址与段地址

对一个程序而言,基地址就是这个程序被机器执行时机器所需要的“东西”(可以是数据也可以代码段等?)的地址,基地址就是这个这个程序的“段”的起始地址,而机器要拿到这些“东西”就需要段地址。换句话说,基地址其实跟段地址是类似的东西。
具体的理解参考百科这个回答:什么是基地址和段地址?主要用途是?

汇编中的 #

# 在汇编中表示立即寻址,举个简单的例子:

1
mov A,#21H

该指令的意思是将值 21H 送给寄存器 A 中暂存,如果把#去掉,那么意思就是将地址 21H 里面的内容送给寄存器 A 了。

汇编中的 .

参考链接:ARM中的汇编指令

姑且认为.byte.text这类指令是 GNU 的伪汇编指令。另外,上述文章中还有很多其他指令的介绍,也可以算作参考资料。

x86 下的寄存器

参考文章里面写的已经很清楚了,但我们目前需要了解的东西比较简单,就是有多少个寄存器,名字叫什么。8086的编程模型包括 8、16 和 32 位的寄存器,按照位分类:

8 位的寄存器包括 AH,AL,BH,BL,CH,CL,DH 和 DL。

16 位寄存器包括 AX,BX,CX,DX,SP,BP,DI,SI,IP,FLAGS,CS,DS,ES,SS,FS,和 GS。

扩展的 32 位的指令包括 EAX,EBX,ECX,EDX,ESP,EBP,EDI,ESI,EIP 和 EFLAGS。

所有的 32 位寄存器和 16 位寄存器中的 FS 或者 GS 都仅仅能够在 80386 以上使用。

参考文章:Intel 80X86寄存器分类介绍

CF

CF 是汇编中的进位标志位,主要用来反映运算是否产生进位或错位。如果运算结果的最高位产生了一个进位或错位,其值就为 1。与之对应的是两个跳转指令: jc 和 jnc,前者当 CF=1 时,跳转,后者反之。

jnc

这条语句的功能有点类似 C 语言中的 goto,但它与 goto 不同的地方在于,它需要有一个进位。换句话说,jnc xxx这条语句之前会有运算,运算的结果会影响 CF 的值。当 CF=0 时,它就会产生与 goto 一样的功能,反之,就跳过这条语句,就是 continue 的功能了。

lds

lds 指从存储器取出 32 位地址的指令,格式有:lds oprd1, oprd2,其中,oprd1 为任意一个 16 位的存储器,oprd2 为 32 位的存储器。

[]

汇编中的 [] 表示一种间接的取操作数的方式,有点类似于 C 语言中的指针概念,具体参考下面这个回答:汇编语言加中括号表示什么?

rep movsb

rep movsb 其实是两个指令,但是一般是联合起来用的,同时在这条指令之前必然要对 cx 这个寄存器的值进行设置,因为 cx 的值代表了重复多少次。具体的细节可以参考这篇文章:汇编中 rep movsb

字、字节、位

字(word)这个概念应该就是针对 cpu 而言的,不严谨的讲,字可能就是 cpu 一次性能处理的指令长度;而字节(byte)是一个存储概念,位(bit)也算是一个存储概念。比如,对 16 位 cpu 而言 1 个字长就是 2 个字节,16 位。所以,不同型号的 cpu ,其字的大小是不一样的,当然了,这样说可能不太严谨。

call

这个指令类似 C 语言中的 goto,但是这个指令执行完子程序后要回来,这是二者的区别。详细参考这个回答:汇编语言中的 call 是什么意思