逆向基础--汇编基础(段的分类) (07)
一.代码段
前面了解,对于8086PC机,再编程时可以根据需要将一组内存单元定义为一个段。长度为N (N<=64kb)的一组代码,存在一组地址连续,起始地址为16倍数的内存单元中,如果这段内存是用来存储代码的,被定义为一个代码段。
mov ax,0000 ;(B8 00 00) ;初始化 AX 寄存器为 0。 如果寄存器是AX,则操作码为B8, 后面跟着低字节00和高字节00 add ax,0123 ;(05 23 01) ;给 AX 加上 0123。 05是ADD指令家族中的一个特定操作码,将16位立即加到AX寄存器。先23后01 mov bx,ax ;(8B D8) ;将AX复制到 BX。 jmp bx ;(FF E3) ;跳转到内存地址 0123 处执行
上面的代码段长度为10个字节(3,3,2,2)的机器码,将它存放在物理地址为123B0H ~ 123B9H的一组内存单元中,就可以说这个范围的内存是用来存放代码的,是一个代码段,段地址为123BH,长度为10个字节。
虽然上面代码设置在一个代码段内,但仅仅是编程时的一种安排,CPU并不会因为这么安排,就自动当做指令来执行。CPU只认被CS:IP指向的内存单元中的内容为指令。
所以需要将CS:IP指向123B0这个单元,也就是需要设置CS=123BH,IP=0000H。
CS中的C是Code; S是segment 指段;
CS是代码段寄存器是存放当前在正运行的程序代码所在段的段基址,表示当前使用的指令代码可以从该段寄存器指定的存储器段中取得,相应的偏移地址是则IP(指令指针寄存器)提供。
二.数据段
当我们要先保存一组数据如: 0123H, 0078H, 96FFH等一组数据。可以设置一个数据段,用来存储这组数据,需要将DS寄存器存放数据段的段地址,当我们在使用数据的时候只需要给出偏移地址就可以了。
mov ax, 123B ;将123B(H)送入到AX寄存器 ax=123BH mov ds,ax ;将AX的值送入DS寄存器DS=123B,作为数据段的段地址(这用不能直接 mov ds,123B) mov al,[0] ;将内地址DS:0处的一个字节数据送入AL寄存器,已知AX寄存器是16位,由AH和AL组成。此命令只改变了AL(AX的低8位)的值。
下图是一个数据段的演示,首先使用debug下的-a在内存中写入机器指令共三条,使用 【-t 】命令来逐行调试:
1) 第一次输入-t 会把第一行的机器指令执行。此时AX=123B , IP=0103
2) 第二次输入-t 会把第二行的机器指令执行。此时AX=123B , DS=123B , IP=0105
3) 使用-d123B:0000命令来查看内存单元的内容,显示第一个字节为 00
4) 第三次输入-t会把第三行的机器指令执行。 此时AX=1200 , DS=123B , IP=0108。 我们知道第三行机器指令的 [0] 是把DS的第一个单元字节00,赋值给了AX下的AL低8位。所以由AX=AH+AL就是AX=12 +3B变成 AX=12 + 00 =1200
DS中的D是Data; S是segment 指段;
DS是数据段寄存器,指出当前程序使用的数据所存放段的最低地址,即存放数据段的段地址。他的偏移量如:[0]
三.栈段寄存器
SS中的S是stack;S是segment 指段;
指出当前堆栈的底部地址,即存放堆栈段的段基址,SS:IP指向栈顶单元
栈是一种具有特殊的访问方式的存储空间,在于后进先出。将元素放入栈的操作称为入栈,从栈中取出元素的操作称为出栈。
入栈就是将一个新的元素放到栈顶,出栈就是从栈顶取出一个元素。
栈的这种操作规则被称为LIFO(last In First Out, 后进先出)
8086CPU同样支持栈,相应的提供了两个指令用于出栈以及入栈:PUSH(入栈)和POP(出栈),在编程时可以将一段内存当成栈来使用,像这样的一段内存称为栈段。
mov ax, 0123 push ax ;将ax的数据0123入栈,压入到栈底 mov bx, 2266 ; push bx ;将bx的数据2266入栈,压入到栈底 mov cx, 1122 ; push cs ;将cs的数据1122入栈,压入到栈底 pop ax ;出栈,最后进入的是1122,所以是将1122的数据给ax pop bx ;出栈,将2266的数据给bx pop cx ;出栈,将0123的数据给cx
演示如下所示,由入栈时ax=0123,出栈时ax=2266;由入栈时bx=2266,出栈时bx=0123

上面示例中,CPU怎么知道段在哪里,又怎么知道这段空间要被当作栈来使用? 那是因为CPU有相应的寄存器标记这个栈空间,同理栈顶也有个寄存器来标记,这就是要讲的SS(栈段寄存器)和SP(栈顶指针寄存器)。栈段地址存放在SS寄存器中,偏移地址存放在SP寄存器中。任意时刻SS:SP指向栈顶元素。push指令和pop指令执行时,CPU从SS和SP中得到栈顶的地址。
下图是演示 SS:SP的地址移动关系,压栈前SP=00FD,压栈后SP=00FB。最后通过-d073F:00F0(SS:SP)可以看出最后SP指针指向00FB,也表示入栈成功

四.附加段数据寄存器
ES中的E是extra, S是segment 指段;
指出当前程序使用附加数据段的段基址,该段是串操作指令中,目的串所在的段。
后面在补上
浙公网安备 33010602011771号