1、 assume cs:code,ds:data,ss:stack start: mov dx,offset string mov ah,9 int 21h code ends end start3.7DOS支持哪两种可执行程序结构,编写这两种程序时需要注意什么?(1). EXE程序 程序可以有多个代码段和多个数据段,程序长度可以超过64KB 通常生成EXE结构的可执行程序(2). COM程序 只有一个逻辑段,程序长度不超过64KB 需要满足一定条件才能生成COM结构的可执行程序(MASM 6.x需要采用TINY模式)3.8举例说明等价“EUQ”伪指令和等号“=”伪指令的用途 符号定义伪指令有“
2、等价EQU”和“等号”: 符号名 EQU 数值表达式 符号名 EQU 符号名 数值表达式 EQU用于数值等价时不能重复定义符号名,但“”允许有重复赋值。例如: X= 7 ;等效于:X equ 7 X= X+5 ;“X EQU X+5”是错误的3.9 给出下列语句中,指令立即数(数值表达式)的值(1)mov al,23h AND 45h OR 67h(2)mov ax,1234h/16+10h3:mov ax,23h SHL 44:mov al, aand(NOT(a-A)5:mov ax,(76543 LT 32768) XOR 7654h (1) al=67h (2) ax=133h,dx=
3、4h (3) ax=0230h (4) al=41h (4) ax=7654h3.10画图说明下列语句分配的存储空间及初始化的数据值(1)byte_var db abc,10,10h,EF,3 dup(-1,?,3,dup(4)(2:)word_var dw 10h,-5,3,dup(?) (1)41h42h43h1010h45h46h-1?4?(2)00h0fbh0ffh3.11 请设置一个数据段,按照如下要求定义变量:(1)my1b为字符串常量,表示字符串“personal Computer”(2)my2b为用十进制数表示的字节变量,这个数的大小为20(3)my3b为用十六进制数表示的字节
4、变量,这个数的大小为20(4)my4b为用二进制数表示的字节变量,这个数的大小为20(5)my5w为20个未赋值的字变量(6)my6c为100的符号常量(7)my7c为字符串常量,代替字符串“personal Computer”.data my1b db Personal Computer my2b db 20 my3b db 14h my4b db 00010100b my5w dw 20 dup(? my6c = 100 my7c = 3.12 希望控制变量或程序代码在段中的偏移地址,应该使用哪个伪指令? 利用定位伪指令控制,如org,even,align3.13名字和符号有什么属性? 包
5、括逻辑地址和类型两种属性。3.14设在某个程序中有如下片段,请写出每条传送指令执行后寄存器AX的内容:;数据段Org 100hVarw dw 1234h,5678hVarb db 3,4Vard dd 12345678hBuff db 10 dup(?Mess db hello ;代码段 Mov ax,offset mess Mov ax,type buff+type mess+type vard Mov ax,sizeof varw+sizeof buff+sizeof mess Mov ax,lengthof varw+lengthof vard org 100h varw dw 1234
6、h , 5678h varb db 3 , 4 vard dd 12345678h buff dd 10 dup(? mess db Hello mov ax , offset varb + offset mess mov ax , type buff + type mess + type vard mov ax , sizeof varw+ sizeof buff+ sizeof mess mov ax , lengthof varw+ lengthof vard3.15假设myword是一个字变量,mybyte1和mybyte2是两个字节变量,指出下列语句中的具体错误原因。(1)mov b
7、yte ptr bx,1000(2)mov bx,offset mywordsi(3)cmp mybyte1,mybyte2(4)mov mybyte1,al+1(5)sub al,myword(6)jnz myword (1) 1000超过一个字节所能表达的最大整数 (2)SI应为偶数 (3)两个内存单元不能直接运算 (4)应改为al+1 (5)条件转移指令后面应接标号,而不是变量3.16编写一个程序,把从键盘输入的一个小写字母用大写字母显示出来 mov ah,1 ;只允许输入小写字母 int 21h sub al,20h ;转换为大写字母 mov dl,al mov ah,2 int 21
8、h ;显示3.17 已知用于LED数码管的显示代码表为:LEDtable db 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8hdb 80h,90h,88h,83h,0c6h,0c1h,86h,8eh它依次表示09,AF这16个数码的显示代码。现编写一个程序实现将lednum中的一个数字(09,af)转换成对应的LED显示代码 mov bx,offset LEDtable mov al,lednum xlat3.18 编制一个程序,把变量bufX和bufY中较大者存入bufZ;若两者相等,则把其中之一存入bufZ中。假设变量存放的是8位有符号数。 mov ax, buf
9、X cmp ax, bufY jae done mov ax, bufYdone: mov bufZ, ax3.19为有符号16位数,请将它们的符号状态保存在signX,即:如果变量值大于等于0,保存0;如果X小于0,保存-1。编写该程序。设变量bufX 解: .model small .stack .databufX dw -7signX db ? .code .startup cmp bufX,0 ;test bufX,80h jl next ;jnz next mov signX,0 jmp donenext: mov signX,-1 .exit 0 end3.20bufX、bufY
10、和bufZ是3个有符号16进制数,编写一个比较相等关系的程序(1)如果这3个数都不相等,则显示0(2)如果这三个数中有两个数相等,则显示1(3)如果这三个数都相等,则显示2 mov dl,2 mov ax,bufX cmp ax,bufY je next1 dec dlnext1: cmp ax,bufZ je next2next2:3.21 例3.7中,如果要实现所有为1的位都顺序执行相应的处理程序段(而不是例题中仅执行最低为1位的处理程序段),请写出修改后的代码段? ; mov al,number mov bx,0 ;BX记录为1的位数restart: cmp al,0 ;AL0结束 jz
11、 doneagain: shr al,1 ;最低位右移进入CF jc next ;为1,转移 inc bx ;不为1,继续 jmp again push ax push bx shl bx,1 ;位数乘以2(偏移地址要用2个字节单元) jmp addrsbx ;间接转移:IPtableBX以下是各个处理程序段fun0: mov dl,0 jmp dispfun1:1fun2:2fun3:3fun4:4fun5:5fun6:6fun7:7disp: mov ah,2 ;显示一个字符 pop bx pop ax jmp restart 3.22 编制程序完成12H、45H、0F3H、6AH、20H
12、、0FEH、90H、0C8H、57H和34H等10个字节数据之和,并将结果存入字节变量SUM中(不考虑溢出和进位)。wjxt322.asmb_data db 12h,45h,0f3h,6ah,20h,0feh,90h,0c8h,57h,34h ;原始数据num equ 10 ;数据个数sum db ?预留结果单元 xor si, si ;位移量清零 xor al, al ;取第一个数 mov cx, num ;累加次数 add al, b_datasi ;累加 inc si ;指向下一个数 loop again ;如未完,继续累加 mov sum, al ;完了,存结果3.23 求主存0040
13、h:0开始的一个64KB物理段中共有多少个空格?; wjxt323.asmstart: mov ax,0040h ;送段地址 mov ds, ax mov si, 0 ;偏移地址 mov cx, si ;计数(循环次数) xor ax, ax ;空格计数器清零 cmp byte ptr si, 20h ;与空格的ASCII码比较 jne next ;不是空格,转 inc ax ;是空格,空格数加1修改地址指针cxcx1,如cx0 退出循环 end start3.24 编写计算100个16位正整数之和的程序。如果和不超过16位字的范围(65535),则保存其和到wordsum,如超过则显示ove
14、rflow。答:count equ 100parray dw count dup(?) ;假设有100个数据wordsum dw 0msg db overflow,$ mov cx,count mov ax,0 mov bx,offset parray add ax,bx jnc next mov dx,offset msg mov ah,9显示溢出信息 jmp done ;然后,跳出循环体 add bx,2 loop again mov wordsum,ax 3.25 编程把个16位无符号二进制数转换成为用8421BCD码表示的5位十进制数。转换算法可以是:用二进制数除以10000,商为“万
15、位”,再用余数除以1000,得到“千位”;依次用余数除以l00、10和l,得到“百位”、“十位”和“个位”。wjxt325.asm .model small .stack 256 .data array dw ?源字数据 dbcd db 5 dup(?五位bcd结果,高对高低对低 .code .startup mov dx, array ;取源数据(余数) mov bx, 10000 ;除数 mov cx, 10 ;除数系数 mov si, 4 ;目的数据高位位移量 mov ax, dx ;dx.ax中存放被除数 mov dx, 0 div bx ;除于bx,商ax,余数dx mov dbcd
16、si, al ;商10,存结果 push dx ;暂存余数 mov ax, bx ;除数除于10 mov dx,0 div cx ;dx.ax除于cx,商ax、余数0存在dx mov bx, ax ;bx是除数 pop dx dec si ;目的数据位移量减1 jnz again mov dbcd, dl ;存个位数( 10 ) 3.26过程定义的一般格式是怎样的?子程序开始为什么常有PUSH指令?返回钱为什么常有POP指令?下面完成16位无符号数累加的子程序有什么不妥吗?若有,请改正。Carzy PROCPush axXor ax,axXor ax,dxAgain add ax,bx Adc
17、 dx,0 Inc bx Loop again Ret ENDP crazy (1)汇编语言中,子程序要用一对过程伪指令PROC和ENDP声明,格式如下: 过程名 PROC NEAR|FAR ;过程体 过程名 ENDP (2)保护用到的寄存器内容,以便子程序返回时进行相应的恢复。 (3)改错: crazy proc pish bx push cx xor ax,ax xor dx,dx again:add a,bx adc dx,0 inc bx loop again pop cx pop bx3.27 编写一个源程序,在键盘上按一个键,将从AL返回的ASC码值显示出来,如果按下ESC键则程序
18、退出。 解(不需调用HTOASC子程序): mov ah,1 cmp al,1bh ;ESC的ASCII码是1bh je done是大写字母则转换为小写字母3.28请按如下说明编写子程序:子程序功能:把用ASC码表示的两位十进制数转换为对应二进制数入口参数:DH=十位数的ASC码,DL=个位数的ASC码出口参数:AL=对应的二进制数 解答:asctob proc push cx and dh,0fh ;先转换十位数 shl dh,1 ;十位数乘以10(采用移位指令) mov ch,dh shl dh,1 add dh,ch and dl,0fh ;转换个位数 add dh,dl ;十位数加个位
19、数 mov al,dh ;设置出口参数 pop cx retasctob endp3.29 调用HTOASC子程序,显示一个字节的16进制数,后跟“H”的子程序。DIPASC proc ;入口参数:AL要显示的一个16进制数 push dx mov cl,4 ;转换高位 shr al,cl call HTOASC mov dl,al ; pop ax ;转换低位 mov dl,H ;显示一个字母“H”DIPASC endpHTOASC proc ;将AL低4位表达的一位16进制数转换为ASCII码 and al,0fh cmp al,9 jbe htoasc1 add al,37h ;是0AH
20、0FH,加37H转换为ASCII码 ret ;子程序返回htoasc1: add al,30h ;是09,加30H转换为ASCII码HTOASC endp3.30写一个子程序,根据入口参数AL=0、1、2,依次实现对大写字母转换成小写、小写转换成大写或大小字母互换。欲转换的字符串在string中,用0表示结束lucase proc mov bx,offset string cmp al,0 je case0 cmp al,1 jz case1 cmp al,2 jz case2case0: cmp byte ptr bx,0 cmp byte ptr bx,A jb next0 cmp byt
21、e ptr bx,Z ja next0 add byte ptr bx,20hnext0: inc bx jmp case0case1: cmp byte ptr bx,a jb next1 cmp byte ptr bx,z ja next1 sub byte ptr bx,20h jmp case1case2: jb next2 ja next20 jmp next2next20: ja next2 jmp case2lucase endp3.31子程序的参数传递有哪些方法?请简单比较 (1)用寄存器传递参数: 最简单和常用的参数传递方法是通过寄存器,只要把参数存于约定的寄存器中就可以了
22、由于通用寄存器个数有限,这种方法对少量数据可以直接传递数值,而对大量数据只能传递地址 采用寄存器传递参数,注意带有出口参数的寄存器不能保护和恢复,带有入口参数的寄存器可以保护、也可以不保护,但最好能够保持一致 (2)用共享变量传递参数 子程序和主程序使用同一个变量名存取数据就是利用共享变量(全局变量)进行参数传递 如果变量定义和使用不在同一个源程序中,需要利用PUBLIC、EXTREN声明 如果主程序还要利用原来的变量值,则需要保护和恢复 利用共享变量传递参数,子程序的通用性较差,但特别适合在多个程序段间、尤其在不同的程序模块间传递数据 (3)用堆栈传递参数 参数传递还可以通过堆栈这个临时存储区。主程序将入口参数压入堆栈,子程序从堆栈中取出参数;子程序将出口参数压入堆栈,主程序弹出堆栈取得它们 采用堆栈传递参数是程式化的,它是编译程序处理参数传递、以及汇编语言与高级语言混合编程时的常规方法3.32采用堆栈传递参数的一般方法是什么?为什么应该特别注意堆栈平衡问题。 方法:主程序将入口参数压入堆栈,
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1