首页 > 编程知识 正文

汇编语言程序设计第五版钱晓捷,dsp实验汇编语言程序设计

时间:2023-05-04 21:18:58 阅读:116101 作者:1717

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

1 .实验的目的和内容

了解子程序的结构特点,熟悉子程序参数传递的方法,掌握子程序的创建。

2、实验内容2.1二进制输入输出子程序(1)编写二进制输入子程序二进制输入子程序,验证子程序的主程序,使其正确运行。

代码想法:(1)在字符输入子程序readc中输入字符,判断是0还是1,如果正确,直接减去30h转换为数值。

)在反复进行文字转换的同时,需要将之前得到的合计值向左移动1位,并与新得到的值相加。

)3)输入非)、0 )或非)、1 )、的数值时,或者数据位数超过了边界时,转移到错误消息。

include io32.inc.datacount=5; 确保5个空间arraydwordcountdup(0; 是否要声明数组temp dword? 工具变量. codestart:movecx,countmov ebx,offset array; 初始化数组指针again:call rdbd; 调用子程序,通过键盘读取数据mov eax,temp; 出口参数mov [ebx],eax; 保存在输入缓冲区call dispbdadd ebx、4中; 数组指针移动loop againexit 0rdbdproc; 二进制输入子程序、推式eax; 出口参数,共享工具变量temppushebxpushecxrdbd 1: xor ebx,ebx; ebx用于存储二进制结果mov ecx、32; 输入字符的数量限制为32个rdbd 2:呼叫自述; 字符cmp al、'0'; 小于0、报告错误的jb rderrcmp al、'1'; 大于1、报告错误的ja rderrsub al、'0'; 获得真实数据shl ebx,1; 之前输入并转换为二进制的数据向左移动一位后再加上or bl、al; bl和al相加后loop rdbd2; 循环输入文字mov temp,ebx; 将ebx二进制结果保存到temp并返回calldispcrlfpopecxpopebxpopeaxretrderr 3360 mov eax,offset errmsg; 错误信息calldispmsgjmprdbd1errmsg byte0DH,0ah,' Inpput error,enter again: ',0rdbd endp; 子程序结束end start运行结果:

)二进制显示子程序创建并正确运行二进制显示子程序和验证子程序的主程序(教材练习问题5.8 )。

代码思路:将得到的二进制数逐位向右移动,通过确定CF是否为1来分别处理。 处理时加30H转换为ACSII码,每次将得到的ACSII码放入堆栈中。 此时,在原始数据中,各位在堆栈中从低到高,输出时依次跳出堆栈是正确的顺序。

include io 32.Inc.dataarraydword 10110101 b、1010000101b、00010001000101 b、10010101010 bwritebufbyte 12 dup (0); 显示缓冲区. codestart:mov ecx,lengthof array; 排列长度计数器mov ebx,0; 数组指针again:mov eax,array[ebx*4]; 逐一取出字符数组中的元素call writecall dispcrlfinc ebx; 数组指针移动loop againexit 0; 子程序的一部分writeprocpush ebx; 数组指针先进先出push ecx; 计数器再入堆栈push edx; 缓冲区中每个二进制文件的edx堆栈mov ebx、offset writebuf; 指向显示缓冲区write1:mov ecx、32的字符内部数组开头指针; 每二进制表示最多32位的push ecx; 结束标志mov edx、0write2:cmp eax、0; 换档结束标志jzwrite3; 所有有效位都向右移动了shr eax,1; 每次向CFjnc write_0输出最低位移; 最低有效位为0jmp write_1 write_0:mov edx、0add edx、30h时; 加入30h转换为ACSII码push edx; 该字符为jmp write2write_1:mov edx,1add edx,30h; 加入30h转换为ACSII码push edx; 此字符将堆栈在jmp write2write3:pop edx中; 对于这个数,从上位向下位依次堆积cmp edx、ecx; 堆栈结束判断jzwrite4mov [ebx],dl; 将堆栈弹出的值放入数组inc ebx中; 数组指针移动jmp write3write 43360 movbyteptr [ ebx ],0; 在显示内容上附加结束标志mov eax,offset writebuf; 打印缓冲区内容calldispmsgpopedxpopecxpopebxretwriteendpendstart执行结果:

2.2主存储区数据显示符

程序

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

代码:

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

运行结果:

2.3 十进制数的输入和显示子程序 (1) 有符号十进制数输入子程序

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

.datacount = 5array dword countdup(0)temp dword ?readbuf byte 30 dup(0).codebegin:mov ecx,countmov ebx,offset array;ebx为数组指针again:call read;调用子程序,输入一个数据mov eax,temp ;获得出口参数mov [ebx],eax;存放到数据缓冲区add ebx,4;指针移动dec ecx;计数器递减jnz again;循环判定条件exit 0;退出主程序readproc;输入有符号十进制数的子程序push eax;出口参数:变量temp= 补码表示的二进制数值push ebx;说明:负数用"-"引导push ecx push edxread0: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 read1cmp al,'-';是'-',设置-1标志jnz read2;转至无符号处理区read2mov ecx,-1;ecx保存符号位read1:inc edx;取下一个字符mov al,[edx]test al,al;是结尾0,转向求补码jz read3read2:cmp al,'0';不是0~9之间的数码,输入错误jb readerrcmp 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 dispmsgjmp read0;read3:test ecx,ecx;判断是正数还是负数jz read4neg ebx;是负数,进行求补jmp read5read4:cmp ebx,7fffffffh;正数超过2^31-1,出错ja readerrread5:mov temp,ebx;设置出口参数pop edxpop ecxpop ebxpop eaxreterrmsgbyte 'error!!',13,10,0readendpend begin (2) 有符号十进制数显示子程序

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

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

程序代码:

include io32.inc.dataarraydword1234567890,-1234,0,1,-987654321,32767,-32768,5678,-5678,9000writebufbyte12 dup (0);显示缓冲区.codestart:mov ecx, lengthof array;数组长度计数器 mov ebx, 0again:mov eax, array[ebx*4];逐个取出字符数组中元素call write ;调用子程序,显示一个数据call dispcrlf inc ebx;数组指针移动loop againexit 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 write5write1: jns write2;是正数,转至write2处理mov byte ptr[ebx],'-';若为负数,则首先给字符数组传入一个负号inc ebx;字符数组指针往后移动neg eax;对eax进行求补write2: mov ecx,10;除数 ecx=10 push ecxwrite3: cmp eax,0;若该位数为0,则转至write4jz write4xor edx,edx;edx,被除数高位清零div ecx;除以10,取余add edx, 30h;余数转化为ACSII码push edx;将最低位数字压栈jmp write3write4: pop edx;从高位到低位依次弹出栈中存放的数字cmp edx,ecx;和除数10进行比较,是结束标志10,转至打印处理je write5mov [ebx],dl;将余数edx的低八位dl放进字符数组inc ebx;数组指针移动,循环输出存放的数jmp write4write5: mov byte ptr[ebx],0;字符数组结束标志mov eax, offset writebuf;打印缓冲区内容call dispmsgpop edxpop ecxpop ebxretwrite endpend start

运行结果:

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

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

程序代码:

include io32.inc.dataarraydword1234567890,1234,0,1,987654321,32767,32768,5678,9000writebufbyte12dup (0);显示缓冲区.codestart:mov ecx, lengthof array;ecx为数组长度计数器mov ebx, 0again:mov eax, array[ebx*4] ;使用共享变量传递参数call write;调用子程序,显示一个数a,需要保存ebx、ecx的值call dispcrlfinc ebx;数组指针移动loop againexit 0;子程序writeprocpush ebxpush ecxpush edxmov ebx, offset writebuf;字符内部数组首指针,指向显示缓冲区test eax,eax;若为0,则直接输出jnzwrite1;若不为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 write2write3:pop edx;从高位到低位依次pop出来cmp edx,ecx;判断该数是否pop完毕jz write4;pop完毕,转至输出缓冲区mov [ebx],dl;把从栈中弹出的数位存至数组,ACSII<127,用dl即可inc ebx;数字内部字符数组,每次增1jmp write3write4:mov byte ptr[ebx],0;数组末尾加0mov eax, offset writebuf;打印缓冲区内容call dispmsgpop edxpop ecxpop ebxretwriteendpend start

(3) 无符号十进制数输入子程序 include io32.inc.datacount = 5;预留5个空间arraydwordcountdup(0);初始化数组tempdword?;工具变量readbufbyte30dup(0);输入缓冲区.codestart:mov ecx,countmov ebx,offset array;ebx为数组指针again:call read;调用子程序,输入一个数据mov eax,temp;将返回的temp传回eaxmov [ebx*4],eax;存放到数据缓冲区inc ebx;数组指针移动loop again;循环将所有数据全部输出exit 0;子程序部分readprocpush 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-1jberead1;没超过,继续取下一个字符readerr:mov eax,offset errmsg;显示出错信息call dispmsgjmp read0;再次输入read2:mov temp,ebx;设置出口参数pop ecxpop ebxreterrmsgbyte 'error!!',13,10,0read endpend start

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。