小知识2

assume cs:code
code segment
start:
mov ax,0a000H   
mov cx 11
s: add ax,ax
loop s

segment ends

end

上面的LOOP S时  ,首先是将(CX)减1,然后若(CX)!=0,则向前转至s:,所以使用CX来控制 add ax,ax的执行次数。

mov ax,0a000H   为什么要加 0 呢,在汇编中 ,第一个字符不允许是字母




在DEBUG中 

MOV AX,[0]  // 表示把  DS:0处的 数据放入到AX

在 masm编译器中

MOV AX,[0] // 则表示 mov ax,0  会当成10进制 0 来看


2.解释

mov al,[0]   //把 十进制 0 放入到AL

mov al,ds:[0]  //把DS地址的第一个地址值放入AL

mov al,[bx] //把 DS地址段偏移量为BX的地址值复制给AL

mov al,ds:[bx] // 同上



loop和[BX]联合使用


3. 一段安全的空间

0:200H ~ 0:2FFH


4. 

reg 的集合包括: ax bx cx dx ah bh ch dh al bl cl dl sp bp si di

sreg:ds ss cs es


在8086CPU中 、只有4个寄存器(bx bp si di) 可以用在[...] 中来进行内存单元寻址

只能 组合  [bx+si]  [bx+di]  [bp+si]   [bp+di]

bp默认的段地址 ss ,类似sp

bx 默认的段地址 ds  


mov ax,bx  把 地址bx里面的值 放到寄存器 ax



指定数据长度

mov word ptr ds:[0],1

inc byte ptr [bx]

必要性如 FFH   

FFH+1=?   如果是字型那么没有问题,但是如果是字节型  就会溢出   00H


上图的指令解说:
首先 cs:ip = 20018H 到对应的内存地址中找相应的指令(01408BH),
把这个机器码读取到 指令缓冲寄存器中,然后执行命令,
是: 取出ds:[bx+si+1]=2000*10+000F+0002+1=20012H 的值(8B07) 放入到寄存器AX中


Call和Ret指令


ret指令用栈中的数据,修改IP的内容,从而实现近转移

CPU执行ret指令时,进行下面2步操作:

(IP)=((ss)*16+(SP))

(sp)=(sp)+2

--- pop IP

retf 指令使用栈中的数据,修改CS和IP的内容,从而实现远转移

CPU执行retf指令时,进行下面两步操作:

(IP)= ((ss)*16+(sp))

(sp)=(sp)+2

(cs)=((ss)*16+(sp))

(sp) =  (sp) +2

pop IP

pop CS


call指令

执行call标号时  相当于进行

push IP

jmp near ptr 标号


CPU在执行call far ptr 标号,相当于执行

push CS

push IP

jmp far ptr 标号


执行 call 16寄存器 相当于


push  IP

jmp 16位 reg


标志寄存器

 标志位 6  ZF ( zero flag)      指令计算的结果为0  zf = 1

              2  PF  (parity flag)   二进制 1的个数为偶数 pf = 1

      7  SF                        指令计算结果为负数  SF=1

              0  CF                       记录最高有效位向更高位的进位值  或者减法的时候向高位的借位值

             11  OF  (overflow flag)           如果结果超过寄存器的范围, OF =1 表示溢出

              10 DF



WINDOWS的实模式、保护模式、虚拟8086模式

      实模式: CS:IP --》 程序段,  段地址+偏移地址 = 20位物理地址

      保护模式:  CS:IP --》 程序段,寻址方式不同。 (为的是起到保护的作用)  程序分等级了(数据段,代码段)


保护模式:  

其中, 0 级代表最高的权限级别, 3 级代表最低的权限级别,

0、1、2为系统级, 环3 为用户级




中断


   MOV AX,0

   jmp short s   ;段内短转移  (范围 -128 ~ 127) (IP)=(IP)+ 8      jmp near 标号(段内近转移 (IP)=(IP)+16  范围:(-32768 ~ 32768))

   add ax,1

s:inc ax




位移是03  

所以执行指令EB03会 跳转到  0005+0003 =  0008  --> IP


jmp far ptr 标号  段间转移 (远转移)

是直接修改 CS:IP的值



EA0B01BD0B  直接修改CS:IP


转移地址在内存中的JMP指令

1. jmp word ptr 内存单元地址(段内转移)

     例如:

     mov  ax, 0123H

      mov ds:[0],ax

      jmp word ptr [0]

 执行后   (IP)=0123H


2. jmp dword ptr 内存单元地址(段间转移)

功能:从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址(CS),低地址处是转移的目的偏移地址(IP)

(CS)=(内存单元地址+2)

(IP)=(内存单元地址)

例如:

 mov ax 0123H

mov ds;[0],ax

mov word ptr ds:[2],0

jmp dword ptr ds:[0]

执行后:(CS)=0 ,(IP)= 0123H  cs:ip = 0000:0123


3. jcxz 指令 

if ((cx)==0)

  jmp short  标号


4.loop指令

  (cx)=(cx)-1

  if((cx)!=0)

       jmp short 标号

要注意编译器对转移位移超界的检测



最简单的汇编程序结构分析

编写1.asm

 

assume cs:codesg
	codesg segment
		start:	mov ax,4c00H
			int 21h
	codesg ends
end start

assume cs:codesg

codesg segment

codesg ends

end start 

是伪指令


start- 程序的如果标识

end 后面的start 与前面入口对应, 也可以不写 默认代码段如果标记

编译链接

masm.exe 1.asm   link 1.obj   或者直接ml 1.asm

16进制 -使用uedit32查看



 PE 文件格式  可以看到前面 512 字节 是PE头相关信息

 最下面是程序的入口


载入 debug  .  debug 1.exe



可以看到 CX 的大小就是 指令的长度  机器码长度 5个字节

DS=0b2f   cs=0b3f 可以知道   ds和CS段地址相差10H    物理地址也就是相差10H*10 = 100H  =256 个字节





PSP功能:  程序和系统通信的接口 



查看 ds后的256个字节

 -u 0b2f:0 100


再往下查看就是指令了 

-u 0b2f:100 20


程序加载后分配空间是以16个字节为单位的,也就是说如果不足16个字节的也分配16个字节。 

如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为 ((N+15)/16)*16










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值