逆向基础--汇编基础(段的分类) (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
image

   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  

image

   上面示例中,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,也表示入栈成功

image

 

四.附加段数据寄存器

  ES中的E是extra, S是segment 指段;

  指出当前程序使用附加数据段的段基址,该段是串操作指令中,目的串所在的段。

  后面在补上

 

posted on 2025-11-05 13:44  花阴偷移  阅读(8)  评论(0)    收藏  举报

导航