鱼C论坛

 找回密码
 立即注册
查看: 3943|回复: 3

[汇编作业] 第十章检测实验及笔记

[复制链接]
发表于 2016-1-7 22:58:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 yundi 于 2016-1-8 14:49 编辑

先来个实验10的第2题,解决除法溢出问题。

一张图理顺寄存器变化
无标题.png

  1. ;不溢出的除法子程序
  2. ;自己发明的表示法:(dx)(ax)/(cx)=(dx)(ax)...(cx)
  3. assume cs:code
  4. code segment
  5. start:        mov dx,000fh
  6.                 mov ax,4240h
  7.                 mov cx,0ah
  8.                 call divdw

  9.                 mov ax,4c00h
  10.                 int 21h

  11. divdw:
  12.                 ;1.先处理被除数高16位(dx)的除法               
  13.                 push bx;子程序用到的寄存器,先入栈保存
  14.                 push ax;被除数低16位(ax)后面要用,也保存到栈中
  15.                 mov ax,dx;因为除数(cx)16位,所以把高16位放到(ax)
  16.                 xor dx,dx;同时让(dx)为0
  17.                 div cx;然后相除(dx)(ax)/(cx)=(ax)...(dx)
  18.                 ;2.再处理被除数低16位(ax)的除法
  19.                 pop bx;被除数低16位出栈
  20.                 push ax;栈保存高16位除后的商
  21.                 ;现在的(dx)保存高16位除后的余数,正好下步可用
  22.                 ;公式中余数*65536,为何此处(dx)不乘?
  23.                 mov ax,bx
  24.                 div cx;(dx)(ax)/(cx)=(ax)...(dx),(ax)正好是结果的低16位
  25.                 mov cx,dx;结果的余数放入cx
  26.                 pop dx;取出高16位除后的商(dx),正好是结果的高16位
  27.                 ;公式中需要*65536,为何此处(dx)直接是结果?
  28.                 pop bx;取出bx原始值
  29.                 ret
  30. code ends
  31. end start
复制代码


小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-1-8 09:08:30 | 显示全部楼层
接着是实验10第1题
  1. ;子程序练习
  2. ;名称:show_str
  3. ;功能:按给定参数输出0结尾的字符串
  4. assume cs:code
  5. data segment
  6.         db 'Welcome to masm!',0
  7. data ends

  8. code segment
  9. start:        mov dh,8        ;行号
  10.                         mov dl,3        ;列号
  11.                         mov cl,2        ;颜色属性
  12.                
  13.                         mov ax,data
  14.                         mov ds,ax
  15.                         mov si,0        ;串首
  16.                         call show_str  ;子程序
  17.                        
  18.                         mov ax,4c00h
  19.                         int 21h
  20.                        
  21. show_str:
  22.                         push ax
  23.                         push es
  24.                        
  25.                         ;找偏移 (es):(dh)*160+(dl)*2
  26.                         mov ax,0b800h
  27.                         mov es,ax
  28.                         mov al,160
  29.                         mul dh        ;结果在(ax)
  30.                         mov bx,ax
  31.                         mov al,2
  32.                         mul dl
  33.                         add bx,ax        ;偏移(bx)
  34.                        
  35.                         ;循环读字符并写入
  36.                         mov ah,cl;先保存颜色属性
  37.                         xor cx,cx;清空cx               
  38.         s0:        mov cl,ds:[si];取出data中第si个字符
  39.                         jcxz ok;(cx)=0如果字符为0跳到ok
  40.                         mov al,cl;暂存字符
  41.                         mov es:[bx],ax;此时 (ah)=颜色属性,(al)=字符,将其保存到b800:偏移 中
  42.                         inc si;下个字符
  43.                         add bx,2;下个显存位置
  44.                         jmp short s0
  45.                        
  46.         ok:        pop es
  47.                         pop ax
  48.                         ret
  49. code ends
  50. end start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-1-9 14:45:05 | 显示全部楼层
实验10的第3题,代码越来越长。不知到win32汇编是啥状况。

  1. ;名称:dtoc
  2. ;功能:将word型数据变为十进制字符串,0结尾
  3. ;参数:(ax) = word型数据
  4. ;                ds:si 串首

  5. assume cs:code

  6. data segment
  7.         db 10 dup (0)
  8. data ends

  9. code segment
  10. start:        mov ax,12666
  11.                 mov bx,data
  12.                 mov ds,bx
  13.                 mov si,0
  14.                 call dtoc;调用子程序,将数据变为字符串并保存到指定位置
  15.                
  16.                 mov dh,8
  17.                 mov dl,3
  18.                 mov cl,2
  19.                 mov si,0
  20.                 call show_str;调用输出子程序
  21.                
  22.                 mov ax,4c00h
  23.                 int 21h
  24.                
  25. dtoc:       
  26.                 push cx
  27. s0:                mov cx,ax
  28.                 jcxz ok1;被除数为0表示循环结束,跳出
  29.                 mov bx,10;12666/10=1266>256,商要用(ax)保存,所以除数要16位(bx),不能(bl)
  30.                 xor dx,dx;12666<65536,除数16位,则被除数必须用到(dx),12666<65536,(dx)置0即可
  31.                 div bx;除后的结果 (ax)...(dx)
  32.                 push dx;保存余数,并将(ax)作为下次循环的被除数
  33.                 inc si;记录循环次数,求得字符串长度
  34.                 jmp short s0               
  35. ok1:        mov cx,si
  36.                 xor si,si
  37. s1:                pop ds:[si];依次出栈,将字符串顺序保存到ds:[si]中
  38.                 mov bl,30h
  39.                 add ds:[si],bl;数值转换为对应ASCII码
  40.                 inc si
  41.                 loop s1
  42.                 mov ds:[si],cx;将0保存到字符串结尾
  43.                 pop cx
  44.                 ret

  45. show_str:;输出字符串子程序
  46.                 push ax
  47.                 push es
  48.                 mov ax,0b800h
  49.                 mov es,ax
  50.                 mov al,160
  51.                 mul dh
  52.                 mov bx,ax
  53.                 mov al,2
  54.                 mul dl
  55.                 add bx,ax               
  56.                 mov ah,cl
  57.                 xor cx,cx
  58. s2:                mov cl,ds:[si]
  59.                 jcxz ok2
  60.                 mov al,cl
  61.                 mov es:[bx],ax
  62.                 inc si
  63.                 add bx,2
  64.                 jmp short s2
  65. ok2:        pop es
  66.                 pop ax
  67.                 ret
  68.                
  69. code ends
  70. end start
复制代码

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-4-5 17:02:21 | 显示全部楼层
ret                 用栈中数据修改ip        相当于 pop ip
retf                用栈中数据修改cs和ip        相当于 pop cs , pop ip



call                将当前ip 或 cs,ip入栈,然后跳转
1.    call 标号                                        相当于 push ip , jmp near ptr 标号
2.    call far ptr 标号                                相当于 push ip , jmp far ptr 标号
3.    call 16位reg                                相当于 push ip , jmp 16位reg
4.    call word ptr 内存单元地址        相当于 push ip , jmp word ptr 内存单元地址(2字节)
5.    call dword ptr 内存单元地址        相当于 push cs , push ip , jmp dword ptr 内存单元地址(4字节)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-13 00:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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