目录

  • 1.实验目的及内容
  • 2、实验内容
    • 2.1 二进制输入输出子程序
      • (1) 二进制输入子程序
      • (2) 二进制显示子程序
    • 2.2 主存区域数据显示子程序
    • 2.3 十进制数的输入和显示子程序
      • (1) 有符号十进制数输入子程序
      • (2) 有符号十进制数显示子程序
      • (3) 无符号十进制数显示子程序
      • (3) 无符号十进制数输入子程序

1.实验目的及内容

理解子程序结构的特点,熟悉子程序参数传递的方法,掌握子程序的编写。

2、实验内容

2.1 二进制输入输出子程序

(1) 二进制输入子程序

编写二进制输入子程序、以及验证子程序的主程序,并运行正确。
代码思路:(1)利用字符输入子程序readc输入一个字符,判断是否是0或1,若合法则直接减去30h转化为数值。
(2) 重复转换字符的同时,需要将前面一次得到的总数值左移一位,并与刚得到的新数值进行相加。
(3) 如果输入了非’‘0’‘或非’‘1’'数值或者数据位数超出边界,则转至报错提示。

         include io32.inc
.data
count   = 5                ;预留五个空间
array   dword count dup(0)  ;声明数组
temp    dword   ?           ;工具变量
.code
start:mov   ecx, countmov ebx, offset array ;初始化数组指针
again:  call rdbd               ;调用子程序,从键盘读一个数据mov eax,temp          ;获得出口参数mov [ebx],eax            ;存放到输入缓冲区call dispbdadd ebx,4               ;数组指针移动loop again   exit 0rdbd  proc                    ;二进制输入子程序、push eax              ;出口参数,共享工具变量temppush ebx    push ecx
rdbd1:  xor ebx,ebx             ;ebx用于存放二进制结果mov ecx,32             ;限制输入字符的个数到32个
rdbd2:  call readc              ;输入一个字符cmp al,'0'             ;比0小,转至报错jb rderr                cmp al,'1'                ;比1大,转至报错ja rderrsub al,'0'                ;获得真正的数据shl ebx,1               ;前边输入后转化为二进制的数据左移一位再相加or bl,al              ;bl和al相加loop rdbd2              ;循环键入字符mov temp,ebx         ;把ebx的二进制结果存放于temp返回call dispcrlfpop ecxpop ebxpop eaxret
rderr:  mov eax,offset errmsg   ;显示错误信息call dispmsgjmp rdbd1
errmsg  byte 0dh,0ah,'Inpput error,enter again:',0
rdbd    endp                    ;子程序结束end start

运行结果:

(2) 二进制显示子程序

编写二进制显示子程序、以及验证子程序的主程序(教材习题5.8),并运行正确。
代码思路:将得到的二进制数每次右移一位,通过判断CF是否为1来分别处理,处理时加30H转化为ACSII码,后将每次得到的ACSII码入栈,此时在原数据中每个位在栈中就是低位到高位了,输出的时候依次从栈中弹出就是正确的顺序。

                     include io32.inc.data
array       dword   10110101b,1010000101b,0001000100001000101b,1001010101010b
writebuf    byte    12 dup (0)      ;显示缓冲区.code
start:mov ecx, lengthof array   ;数组长度计数器mov ebx, 0                  ;初始化数组指针
again:      mov eax, array[ebx*4]       ;逐个取出字符数组中元素call writecall dispcrlfinc ebx                      ;数组指针移动loop againexit 0;子程序部分
write       procpush ebx                    ;数组指针先入栈push ecx                    ;计数器再入栈push edx                 ;存放每个留在缓冲区的二进制数的edx入栈mov ebx, offset writebuf   ;字符内部数组首指针,指向显示缓冲区
write1:     mov ecx,32                  ;每个二进制数最多表示到32位push ecx                 ;结束标志入栈mov edx,0
write2:     cmp eax,0                   ;移位结束标志jz   write3                  ;所有有效数字位已经右移完毕 shr eax,1                    ;每次将最低位移出来到CFjnc write_0                    ;若最低位为0jmp write_1
write_0:    mov edx,0add edx,30h                    ;加30h转换为ACSII码push edx                  ;该字符入栈jmp write2
write_1:    mov edx,1add edx,30h                    ;加30h转换为ACSII码push edx                  ;该字符入栈jmp write2
write3:     pop edx                     ;对该数从高位到低位依次出栈cmp edx,ecx                   ;出栈结束判断jz   write4mov [ebx],dl              ;将栈中弹出的值放入数组inc ebx                     ;数组指针移动         jmp write3
write4:     mov byte ptr[ebx],0         ;给显示内容加上结尾标志mov eax,offset writebuf     ;打印缓冲区内容call dispmsg                pop edxpop ecxpop ebxret
write       endpend start

运行结果:

2.2 主存区域数据显示子程序

编写逐个字节显示主存区域数据的子程序和主程序(教材习题5.13),并运行正确。
代码思路:利用十六进制字节显示程序,将主存区域的数据(如字符数组)按字节从低位(字符数组首元素)到高位进行输出即可,每按字节输出一个两位十六进制数数组指针移动一位。

代码:

             include io32.inc.data
array       byte    'This is a test.'
writebuf    byte    12  dup (0)     ;显示缓冲区.code
start:      mov eax,offset array                ;将数组主存偏移地址给eaxmov ecx,lengthof array                ;ecx存放字节数call dispmem                       ;调用子程序按字节从低地址到高地址输出exit 0;子程序部分
dispmem     procpush eax                        ;保护eaxpush ecx                      ;保护ecx          mov ebx,eax                     ;先把整体32位传给ebx,ebx做数组指针
again:      mov eax,[ebx]                   ;把数组中元素传给eaxcall disphb                     ;利用十六进制字节显示子程序mov eax, 32                       ;输出空格call dispc         inc ebx                         ;指针移动loop againdispmem endp                 ;子程序结束end start         

运行结果:

2.3 十进制数的输入和显示子程序

(1) 有符号十进制数输入子程序

编写有符号十进制数的输入子程序、以及验证子程序的主程序,并运行正确。
思路:(1)首先判断数据是否是0、负数或正数,是0则直接显示’0’退出。
(2) 若输入有符号数为负数,显示符号’-’,求数据的绝对值。
(3) 数据除以10,如十进制正数123,
编写无符号十进制数的输入输出子程序、以及验证子程序的主程序,并运行正确。

.data
count   = 5
array   dword   count   dup(0)
temp    dword   ?
readbuf byte    30  dup(0).code
begin:
mov     ecx,count
mov     ebx,offset array    ;ebx为数组指针
again:  call read           ;调用子程序,输入一个数据mov eax,temp        ;获得出口参数mov [ebx],eax        ;存放到数据缓冲区add ebx,4          ;指针移动dec ecx                ;计数器递减jnz again         ;循环判定条件exit 0               ;退出主程序read  proc                ;输入有符号十进制数的子程序push eax          ;出口参数:变量temp= 补码表示的二进制数值push ebx           ;说明:负数用"-"引导push ecx           push edx
read0:  mov eax,offset readbufcall readmsg      ;输入一个字符串test eax,eax        ;没有输入数据,转向错误处理cmp eax,12         ;ja readerr         ;输入超过12个字符,转向错误处理mov edx, offset readbuf ;edx指向输入缓冲区xor ebx,ebx          ;ebx保存结果xor ecx,ecx         ;ecx为正负标志,0为正,-1为负mov al,[edx]        ;取一个字符cmp al,'+'         ;是"+",继续jz read1         cmp al,'-'            ;是'-',设置-1标志jnz read2          ;转至无符号处理区read2mov ecx,-1            ;ecx保存符号位
read1:  inc edx             ;取下一个字符mov al,[edx]test al,al           ;是结尾0,转向求补码jz read3
read2:  cmp al,'0'            ;不是0~9之间的数码,输入错误jb readerr           cmp al,'9'            ja readerrsub al,30h            ;是0~9之间的数码,转换为二进制数imul ebx,10            ;原数值乘10:ebx = ebx *10jc readerr         ;乘积溢出处理movzx eax,al     ;零位扩展,便与相加add ebx,eax           ;原数值乘10后与新数值相加cmp ebx,80000000h ;数据超过2^31,出错
readerr: mov eax,offset errmsg  ;显示出错信息call dispmsg     jmp read0
;
read3:  test ecx,ecx        ;判断是正数还是负数jz read4neg ebx               ;是负数,进行求补jmp read5
read4:  cmp ebx,7fffffffh   ;正数超过2^31-1,出错ja readerr
read5:  mov temp,ebx        ;设置出口参数pop edxpop ecxpop ebxpop eaxret
errmsg  byte 'error!!',13,10,0
read    endpend begin  

(2) 有符号十进制数显示子程序

编写有符号十进制数的显示子程序、以及验证子程序的主程序,并运行正确。

代码思路:(1) 首先判断给的数据是否是0,若为0则直接输出’0’。
(2) 是负数就在数组首端放置’-’,并求数据绝对值。
(3) 数据除以10,余数为10进制数码,加30h转化为ACSII码之后放在字符数组edx中保存。
(3) 重复(3),直到商为0时结束。

程序代码:

         include io32.inc.data
array       dword   1234567890,-1234,0,1,-987654321,32767,-32768,5678,-5678,9000
writebuf    byte    12 dup (0)      ;显示缓冲区.code
start:          mov ecx, lengthof array ;数组长度计数器 mov ebx, 0
again:  mov eax, array[ebx*4]           ;逐个取出字符数组中元素call write                      ;调用子程序,显示一个数据call dispcrlf      inc ebx                         ;数组指针移动loop again                           exit 0;子程序部分
write   procpush ebxpush ecxpush edxmov ebx, offset writebuf        ;字符内部数组首指针,指向显示缓冲区test eax,eax                  ;判断正/负数(结果不为0),0(结果为0),jnz write1                       ;结果不为0,要么正,要么负,转至write1进一步mov byte ptr[ebx],'0'inc ebx                            ;按字节来,数组指针每次增一jmp write5
write1: jns write2                      ;是正数,转至write2处理mov byte ptr[ebx],'-'           ;若为负数,则首先给字符数组传入一个负号inc ebx                          ;字符数组指针往后移动neg eax                          ;对eax进行求补
write2: mov ecx,10                      ;除数 ecx=10 push ecx
write3: cmp eax,0                       ;若该位数为0,则转至write4jz write4                      xor edx,edx                     ;edx,被除数高位清零div ecx                          ;除以10,取余add edx, 30h                 ;余数转化为ACSII码push edx                        ;将最低位数字压栈jmp write3
write4: pop edx                         ;从高位到低位依次弹出栈中存放的数字cmp edx,ecx                       ;和除数10进行比较,是结束标志10,转至打印处理je write5                       mov [ebx],dl                    ;将余数edx的低八位dl放进字符数组inc ebx                          ;数组指针移动,循环输出存放的数jmp write4
write5: mov byte ptr[ebx],0             ;字符数组结束标志mov eax, offset writebuf       ;打印缓冲区内容call dispmsg                    pop edxpop ecxpop ebxret
write   endpend start

运行结果:

(3) 无符号十进制数显示子程序

代码思路:(1) 首先判断给的数据是否是0,若为0则直接输出’0’。
(2 数据除以10,余数为10进制数码,加30h转化为ACSII码之后放在字符数组edx中保存。
(3) 重复(3),直到商为0时结束div。
(4) 持续pop出栈顶元素给edx,此时出栈顺序刚好是从高位到低位。

程序代码:

             include io32.inc.data
array       dword   1234567890,1234,0,1,987654321,32767,32768,5678,9000
writebuf    byte    12  dup (0)     ;显示缓冲区.code
start:      mov ecx, lengthof array         ;ecx为数组长度计数器        mov ebx, 0
again:mov eax, array[ebx*4]             ;使用共享变量传递参数call write                       ;调用子程序,显示一个数a,需要保存ebx、ecx的值call dispcrlfinc ebx                          ;数组指针移动loop againexit 0;子程序write        proc    push ebxpush ecxpush edxmov ebx, offset writebuf        ;字符内部数组首指针,指向显示缓冲区test eax,eax                   ;若为0,则直接输出jnz    write1                      ;若不为0,则进一步处理mov byte ptr[ebx],'0'         ;直接填充字符0inc ebx                         ;数组指针后移jmp write4                       ;转至打印缓冲区
write1:     mov ecx,10                      ;被除数ecx= 10push ecx                        ;结束标志,当edx==ecx时结束popwrite2:      cmp eax,0                       ;判断商是否为0jz write3                       ;商为0,准备输出xor edx,edx                        ;被除数最高位清零div ecx                            ;商不为0,继续作除法add edx, 30h                  ;余数转化为ACSII码push edx                        ;余数(0~9区间)入栈jmp write2
write3:     pop edx                         ;从高位到低位依次pop出来cmp edx,ecx                       ;判断该数是否pop完毕jz write4                       ;pop完毕,转至输出缓冲区mov [ebx],dl                   ;把从栈中弹出的数位存至数组,ACSII<127,用dl即可inc ebx                         ;数字内部字符数组,每次增1jmp write3
write4:     mov byte ptr[ebx],0             ;数组末尾加0mov eax, offset writebuf     ;打印缓冲区内容call dispmsg    pop edxpop ecxpop ebxret
write       endp    end start

(3) 无符号十进制数输入子程序

             include io32.inc.data
count   = 5                                ;预留5个空间
array   dword   count   dup(0)          ;初始化数组
temp    dword   ?                       ;工具变量
readbuf byte    30  dup(0)              ;输入缓冲区  .code
start:      mov ecx,count       mov ebx,offset array            ;ebx为数组指针
again:      call read                       ;调用子程序,输入一个数据mov eax,temp                    ;将返回的temp传回eaxmov [ebx*4],eax                   ;存放到数据缓冲区inc ebx                            ;数组指针移动loop again                       ;循环将所有数据全部输出exit 0;子程序部分
read        proc    push ebx                        ;主程序中数组指针,需要保护push ecx                      ;主程序中计数器,需要保护
read0:      mov eax,offset readbuf          ;输入缓冲区首地址传给eaxcall readmsg                  ;输入一个字符串test eax,eax                    ;没有输入数据,转向错误处理cmp eax,12                     ;输入若超过12个字符,则转向错误处理ja readerrmov edx, offset readbuf         ;edx作为数组指针xor ebx,ebx                       ;ebx保存结果
read1:          mov al,[edx]                    ;从数组中取出一个字符test al,al                       ;判断是不是字符串结尾jz read2                     ;是结尾,输出该数inc edxcmp al,'0'                     ;若某一位小于0,输入错误jb readerrcmp al,'9'ja readerrsub al,30h                      ;ACSII码转化为0~9区间的数imul ebx,10                        ;ebx = ebx*10,给权重,初始时ebx=0jc readerr                        ;乘积溢出处理movzx eax,al                 ;零位扩展,便于前数ebx和当前位al相加add ebx,eaxcmp ebx,0ffffffffh              ;判断数据是否超过2^32-1jbe  read1                       ;没超过,继续取下一个字符
readerr:    mov eax,offset errmsg           ;显示出错信息call dispmsg                 jmp read0                       ;再次输入
read2:      mov temp,ebx                    ;设置出口参数pop ecxpop ebxret
errmsg      byte 'error!!',13,10,0
read        endpend start

汇编语言程序设计实验(六)——子程序设计相关推荐

  1. 计算机组成原理汇编程序实验,计算机组成原理汇编语言程序设计实验.ppt

    汇编语言程序设计实验主讲:马冰汇编语言上机操作步骤汇编语言上机所必备的软件汇编语言上机操作过程汇编语言上机所必备的软件操作系统:DOS或CCDOS编辑程序:行编辑程序EDLIN.COMWPS全屏编辑程 ...

  2. 电子科大计算机调试,电子科大计算机学院 汇编语言程序设计 实验报告 99分精品版.doc...

    电子科技大学 计算机科学与工程 学院 标 准 实 验 报 告 (实验)课程名称 汇编语言与微机接口技术综合实验 电子科技大学教务处制表 电 子 科 技 大 学 实 验 报 告 (一) 学生姓名:郫县英 ...

  3. 微机原理与接口技术实验:子程序设计实验

    学生实验报告 实验课名称:微机原理与接口技术 实验项目名称:子程序设计实验 实验名称:单指令功能的实现 一. 实验目的 1.掌握汇编语言源程序子程序设计方法:. 二.实验内容 设计一个程序,将所有的小 ...

  4. python大学课程实验六_Python程序设计实验六:函数

    安徽工程大学 Python程序设计 实验报告 班级  物流191   姓名姚彩琴学号3190505129 成绩 日期     2020.5.3     指导老师修宇 [实验目的] 掌握函数的定义与使用 ...

  5. 南邮汇编语言程序设计实验二————用户登录验证程序的设计

    目录 实验环境(实验设备) 实验要求 实验代码 相关函数 实验结果 实验环境(实验设备) 硬件:微型计算机 软件:Windows 操作系统.汇编语言开发工具MASM或TASM 实验要求 1. 程序执行 ...

  6. 汇编语言程序设计实验——字符统计

    [实验题目]字符统计 [实验内容]从键盘上输入一个字符串,然后统计英文字母.数字字符和其他字符的个数并输出 [实验目的] 1. 掌握输入字符串的DOS功能调用 2. 掌握分支程序设计方法 3. 掌握二 ...

  7. 南京邮电大学汇编语言程序设计实验一(汇编语言语法练习与代码转换)

    文章目录 一.程序改错(显示25+9=34) 二.统计字符串(42H~45H) 一.程序改错(显示25+9=34) 排除语法错误:给出的是一个通过比较法完成8位二进制数转换成十进制数送屏幕显示功能的汇 ...

  8. 汇编语言程序设计 实验九

    实验内容 实验一: 补全程序t1.asm,完成在屏幕上输出内存单元中的十进制两位数 ; 在屏幕上输出内存单元中的十进制两位数 assume cs:code, ds:data data segmentd ...

  9. 汇编语言程序设计实验报告三

    南京信息工程大学实验报告 实验名称 实验 3 编程.编译.连接.跟踪 实验日期2018.11.18 得分 学院 计软院 专业 计算机科学与技术 年级 2017级 班次  5班   姓名 陈奕明  学号 ...

  10. 南京邮电大学汇编语言程序设计实验一:汇编语言语法练习与代码转换

    一.实验目的和要求 1. 掌握汇编语言源程序的格式: 2. 进一步学习汇编语言源程序的编辑.汇编.目标文件的链接和可执行文件的执行全过程: 3. 掌握编辑软件.TASM/MASM.TLINK和TD的使 ...

最新文章

  1. php数组重复值销毁,如何从PHP中删除数组中的重复值
  2. ftp 425 问题
  3. c语言编一个dll 用message box 弹出一个对话框,Qt学习之路(17): Qt标准对话框之QMessageBox...
  4. golangsha1解码_golang中几种加密方式的处理
  5. alpha事后诸葛亮
  6. 大话目标检测经典模型(RCNN、Fast RCNN、Faster RCNN)
  7. linux双网卡绑定同一IP步骤,linux系统双网卡绑定单个IP地址
  8. Axure5.1不能输入中文问题.
  9. LoadRunner培训初级教程
  10. 一文快速理解23种经典设计模式
  11. IT江湖,哪个门派最挨踢?
  12. linux下使用 sb接口扫描仪,怎样在Linux下设置和使用扫描仪.doc
  13. 考研408(操作系统、计算机组成原理、数据结构、计算机网络)
  14. 推荐一个node QQ机器人框架-onebot
  15. C语言中的绝对值函数
  16. [ECCV2022]3D face reconstruction with dense landmarks
  17. 【UCOSii源码解析】任务间通讯与同步
  18. Linux驱动 | 加载.ko驱动模块的两种方法(insmod与modprobe)
  19. 表或视图不存在的解决方法
  20. 基于用户的协同过滤与基于物品的协同过滤比较

热门文章

  1. android mvp快速创建,学习MVPArms历程之Android Studio快速创建MVPArms项目
  2. Java中回调函数详解
  3. 粒子群算法优化BP和Elman神经网络-matlab源码
  4. 【ELAMN预测】基于遗传算法优化ELMAN神经网络实现电力符合数据回归预测附matlab代码
  5. oracle alter命令大全
  6. Eclipse中文版代码自动补全设置
  7. 王道计算机考研数据结构—学习笔记Chapter Five 串String
  8. 图解TCPIP---第六章---传输层TCPUDP
  9. [绍棠] 如何为iOS app添加AirDrop文件分享功能
  10. Excel常用函数+数据透视表