找回密码
 立即注册
查看: 2166|回复: 0

汇编语言笔记 (第八章)

[复制链接]

78

主题

109

回帖

1023

积分

高级会员

积分
1023

猴年

龙龙实名认证 发表于 2015-6-22 03:00:14 | 显示全部楼层 |阅读模式
  首先是寄存器了,这里我们统计下之前所学的寄存器
  首先四个:ax,bx,cx,dx,
  si,di,sp,ip,(bp),(pws)
  cs,ds,ss,(es)
  其中:ax,bx,cx,dx,这四个可分为高低8位寄存器
  如ah,al....
  其中cx 用来计算循环次数
  bx一般当做偏移地址来说时,段地址在ds中
  其中cs,ds,ss,es这四个为段寄存器
  cs和ip为组合,          定义指令指针
  ss和sp为组合,          定义栈
  ds和bx,si,di组合,定义数据
  关于es以后再说
  bp下面说
  pws以后再说
  其中si,di与bx功能相似,作为偏移地址时,段地址都在ds中
  不一样的是不能向bx一样可以划分为单独的两个8位寄存器
  十四个寄存器中,唯一没有接触过的是:es段寄存器,pws寄存器
  bp寄存器
  说了这么说,就介绍下bp寄存器
  bp寄存器,实际上和sp很相似,默认段地址都在ss中,BP可以间
  接寻址寄存器而SP不能以外,其余的功能基本相同
  如:
  mov ax,[bp]
  就等于:
  ax=ss*16+(bp)
  关于,bx,bp,si,di四个寄存器的配合
  很多人晕,我是这样记的:
  假设:
  bx和bp是两个男人,像我一样帅!呵呵,bx是我本人,bp就是你
  了,他们名字的姓分别是bx姓ds      bp姓ss
  si和di是两个女孩 很漂亮是亲姐妹,比如si是丁丁(人名),di是斜阳(人名),等
  下封ID了...
  idata呢,就是小三了,像谁呢?你猜
  一共5个人哈!记好!
  根据我多年对易术天圆地方的研究!以及我多年的物理学经验,终
  于得出一个结论:正负相吸,相同排斥的原理!
  男女搭配的常规的四种搭配方式:
  [bx+si]
  [bx+di]
  分别是:我和丁丁,我和斜阳            
  [bp+si]
  [bp+di]
  分别是:你和丁丁,你和斜阳  
  当然,如果想搞小三的话,那可以加上idata,甲鱼(人名)常常
  [bp+si+idata...]
  多少个idata,谁知道呢???
  如:
  [bx+si+idata]
  那这样就是,我和丁丁,外加小三....  这种三人关
  系还是可以的,我喜欢....
  你有钱的话,还可以多找几个小三,像甲鱼一样:
  [bx+si+idata+idata+...]
  注意:绝不允许两个男人娶一个老婆,如:
  [bx+bp+si]
  如,我和甲鱼和丁丁,  这样甲鱼是肯定不会愿意的
  ,所以甲鱼只好走了,就剩我和丁丁,如:[bx+di]
  当然这个时间
  我还可以找个小三 ,如[bx+si+idata]
  但是不能找斜阳了,不然就乱伦了...那就是[bx+si+di]
  这样绝对不
  行
  还有就是连同小三我们五个人都单身一辈子,都单身一辈可以5个
  单独出现,所以说:
  亲!你是不是经常男女搭配啊!
  亲!你是不是经常乱伦啊!
  亲!你是不是经常同性恋啊!
  亲!你是不是经常包小三啊!
  亲!你是不是经常单身啊!
  有木有???
  还有就是si和di不能一起,因为乱伦了!
  注意:si可以单独和idata在一起,哎!这个关系怎么可以?设计
  CPU的人啊!伤不起...
  最后讨论下生出孩子的问题,主要是孩子姓什么?
  注意一点:
  [bp+idata]
  [bp+di+idata]
  [bp+si]
  很多人认为,bp段地址在ss,di或者si段地址在ds
  这样是错误的!
  只要bp出现,那就是统一段地址在ss中
  这样理解:
  bp和bx说了是男人,si和di是女人,
  夫唱妇随,孩子出生肯定跟随bp的姓了,那就是段地址在ss
  idata是小三!
  呵呵,肯定也是男的是bp就跟ss,是dx就跟ds
  如果小三和si与di在一起了,那就跟si和di的姓,也是ds
  说下数据处理和数据有关的方面
  首先cpu处理数据,一般不关心数据值是多少,而是关心数据所在
  位置,一般有三种操作,读,写,运行
  一般数据在三个位置:
  内存地址 如:mov ax,[bx]或mov ax,[bx+2]
  cpu内部,如寄存器中,指令缓冲器...  mov ax,bx或者mov ax,1
  端口 暂时不说
  数据进行运算时,一般不需要指定数据运算的单位,如字还是字节
  那是因为很多运算使用了寄存器
  如:mov ax,bx  默认就是字运算  如mov ax,1122h
  注意:mov ax,12h  也是字运算,不要看只有12h就以为是字节运算
  其实编译器当0012h
  mov al,bl   默认是字节运算  如 mov al,22h
  push和pop默认是字运算
  如果在没有指定寄存器的情况下,不指定运算单位,就是要出错的
  程序如下:
  假设数据:
  ds:0   11 22 00 00....
  我们修改11为33,就是 33 22 00 00...
  原来程序如下:
  assume cs:qq,ds:ee
  ee segment
  db 11h,22h
  ee ends
  qq segment
  start:
  mov ax,ee
  mov ds,ax
  mov bx,0
  mov [bx],33h
  mov ax,4c00h
  int 21h
  qq ends
  end  start
  这样的话,结果是
  ds:0   33 00 00 00
  我们虽然修改了11,但同时也把22给修改了
  因为此时没有出现寄存器,所以cpu就认为是字运算了
  ,如果我们要单独修改11的话,那就用一条新指定
  XX ptr
  解析:xx可以是word或者byte...
  如字运算: mov word ptr[bx],33h
  如字节运算:mov byte ptr[bx],33h
  这样的话,我们改进上面的程序,把mov [bx],33h
  这一句修改为:mov byte ptr[bx],33h  
  程序结果如下:
  ds:0  33 22 00 00
  这样就做到没有修改到22这个数据!
  关于寻址方式加定义处理数据单位的综合因为:
  我就写了个最简单的例子,没有用到循环和别的,就是让大家
  更明了
  assume cs:qq,ds:ee
  ee segment
  db'IBM'
  db'100'
  db'PDF'
  db'in'
  ee ends
  qq segment
  start:
  mov ax,ee
  mov ds,ax
  mov bx,0
  mov byte ptr[bx+03h],'0'
  mov byte ptr[bx+04h],'1'
  mov byte ptr[bx+05h],'0'
  mov byte ptr[bx+06h],'d'
  mov byte ptr[bx+07h],'o'
  mov byte ptr[bx+08h],'c'  只修改一个字节
  mov word ptr[bx+09h],'hh'  同时修改1个字
  mov ax,4c00h
  int 21h
  qq ends
  end start
  好了,第八章上半部分就说的这里!
  第八章:
  DIV命令
  除法命令
  说下我们之前学过的运算
  add 加sub减inc自加1div除
  了解基本除法运算
  9/2=4...1
  9是被除数
  2是除数
  4是商
  1是余数
  在8086汇编中,除数可能有8位与16位两种
  除数为8位时,被除数为16位,默认放在ax寄存器中
  商则放在al中,余数放在ah中
  例:
  div byte ptr [bx]
  商al=(ax)/(ds*16+bx)
  余ah=(ax)/(ds*16+bx)
  如果除数为16位时,被除数为32位,默认放在ax和dx中,
  其中bx存放高16位,ax存放低16位
  商则放在ax中,余数则放在dx中
  例:
  div word ptr [bx+si+6]
  商ax=(dx*10000H+ax)/(ds*16+bx+si+6)
  余dx=(dx*10000H+ax)/(ds*16+bx+si+6)
  这里的10000H解析下:
  如果32位数据为:
  AABBCCDD
  那么AABB放在bx寄存器中
  CCDD放在ax寄存器中
  那么AABB*10000H时,也就是等于AABB0000
  这个时间加上ax的值,那就是AABBCCDD
  注意,一定要拿word ptr或者byte ptr指明是字节
  还是字操作,也就是8位还是16位   
  举个例子
  1000/101=9...101
  程序如下:
  assume cs:qq,ds:ee
  ee segment
  db 65h  ;65h即等于十进制101
  ee ends
  qq segment
  start:
  mov ax,ee
  mov ds,ax
  mov ax,3E8h ;3E8h即等于十进制1000
  mov bx,0
  div byte ptr [bx]
  mov ax,4c00h
  int 21h
  qq ends
  end start
  结果:ax=5B09
  其中al=09即是商 ,十进制也是9
  ah=5B即是余数 5Bh即十进制101
  伪指令dd
  其实前面我们说过了,
  db定义字节    8位
  dw定义字     16位
  dd定义双字  32位
  dup这个命令很有用,大家在使用一段干净内存空间时
  可以用它来定义
  dup功能:
  XX y dup(a,b,c)
  其中XX可以是dd,dw,db...
  y即是重复的次数
  括号内部的a,b,c即是要重复的内容
  如
  db 3 dup(11,22)
  执行后,相当于
  db 11,22,11,22,11,22
  关于实验7,我用了一个笨方法下了出来,虽然笨,但是几乎用到
  了前面的所有的知识
  我把代码写下来
  assume cs:qq,ds:ee
  ee segment
  db '1991','1992','1993','1994','1995','1996'
  dd 16,22,382,1356,8000,5937000
  dw 3,7,9,13,38,30000,17800
  ee ends
  ;qq段开始
  qq segment
  start:
  mov ax,ee
  mov ds,ax
  mov ax,1000h
  mov ss,ax
  ;年份计算
  mov bp,0
  mov bx,0
  mov si,0
  mov cx,6
  s:
  mov es,cx
  mov cx,4
  s1:
  mov  word ptr ax,[bx]
  mov  word ptr [bp+si],ax
  inc bx
  inc bp
  loop s1
  mov cx,es
  add si,12
  loop s
  ;中间空格
  mov bp,0
  mov cx,6
  s2:
  mov byte ptr [bp+4],0
  add bp,16
  loop s2
  ;收入计算
  mov cx,6
  mov bx,18h
  mov si,0
  mov bp,0
  s3:
  mov es,cx
  mov cx,2
  s4:
  mov word ptr ax,[bx]
  mov word ptr [bp+si+5],ax
  add bx,2
  add bp,2
  loop s4
  mov cx,es
  add si,12
  loop s3
  ;中间空格
  mov bp,0
  mov cx,6
  s5:
  mov byte ptr [bp+9],0
  add bp,16
  loop s5
  ;雇员数计算
  mov cx,6
  mov bx,30h
  mov si,0
  mov bp,0
  s6:
  mov es,cx
  mov cx,1
  s7:
  mov  ax,[bx]
  mov [bp+si+10],ax
  add bx,2
  inc bp
  loop s7
  mov cx,es
  add si,15
  loop s6
  ;中间空格
  mov bp,0
  mov cx,6
  s8:
  mov byte ptr [bp+12],0
  add bp,16
  loop s8
  ;最后的空格
  mov bp,0
  mov cx,6
  s9:
  mov byte ptr [bp+15],0
  add bp,16
  loop s9
  ;除法运算,商保存偏移OD处,余保存0E处
  mov bp,0
  mov cx,6
  mov si,0
  ps:
  mov bx,0
  mov ax,[bp+si+5]
  mov dx,[bp+si+7]
  div word ptr [si+bp+10]
  mov [bp+si+13],ax
  mov [bp+si+14],dx
  add si,16
  loop ps
  ;结束
  mov ax,4c00h
  int 21h
  qq ends
  end start
  书上原题,答案是这样的:
  assume cs:code,ds:data,es:table
  data segment
  db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
  db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
  db '1993','1994','1995'
  dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
  dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
  dw 11452,14430,15257,17800
  data ends
  table segment
  db 21 dup ('year summ ne ?? ')
  table ends
  code segment
  start:  mov ax,data
  mov ds,ax
  mov ax,table
  mov es,ax
  mov bx,0
  mov si,0
  mov di,0
  mov cx,21
  s:      mov ax,[bx]
  mov es:[si],ax
  mov ax,[bx].2
  mov es:[si].2,ax
  mov ax,[bx].84
  mov es:[si].5,ax
  mov dx,[bx].86
  mov es:[si].7,dx
  div word ptr ds:[di].168
  mov es:[si].13,ax
  mov ax,[di].168
  mov es:[si].10,ax
  add di,2
  add bx,4
  add si,16
  loop s
  mov ax,4c00h
  int 21h
  code ends
  end start
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|虫虫联盟 ( 备案号:蜀ICP备15018121号-1 )

GMT+8, 2026-4-19 13:06 , Processed in 2.414975 second(s), 25 queries .

Powered by Discuz! X5.0 Licensed

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表