常见汇编代码
来源:互联网 发布:怎样制作炒股票软件 编辑:程序博客网 时间:2024/06/05 07:03
常见汇编代码
编写程序:比较AX,BX,CX中带符号数的大小,将最大的数放在AX中
code segment assume cs:code mov ax,32 mov bx,74 mov cx,23sort: cmp ax,bx jge X ;如果ax大于等于bx就跟cx比较 xchg ax,bx X:cmp ax,cx ;如果ax大于cx jge Y xchg ax,cx Y:int 21h mov ax,4c00hcode ends end sort
2.要求对键盘输入的小写字母用大写字母显示出来
code segment assume cs:code start: mov ah,1 int 21h cmp al,'a' jz error cmp al,'z' ja error sub al,20h ;'A'~'Z':41~5AH ‘a'~'z':61~7ah mov dl,al mov ah,2 int 21h jmp start error:retcode ends end start
3.编写程序:从键盘上接收一个四位数的十进制数,并在终端上显示出与它等值的二进制数。
code segment assume cs:code begin:xor bx,bx ;清空bx mov ch,4 mov cl,4 ;设置内外层的循环次数 input:shl bx,cl ;bx中的内容逻辑左移 mov ah,1 int 21h ;输入 cmp al,30h ;是否小于0 jb input ;是就重新输入 cmp al,39h ;是否大于9 ja input and al,0fh ;转换为相应的二进制 jmp combine combine:or bl,al dec ch jnz input display:mov cx,16 ;输出的循环次数 print:mov dl,0 rol bx,1 rcl dl,1 or dl,30h ;清空dl mov ah,2 int 21h loop print ret code ends end begin
4.将内存ffff:0~ffff:d单元中的数据复制到0:200~0:20d单元中。
code segment assume cs:code mov bx,0 mov cx,0fh copy:mov ax,0ffffh mov ds,ax mov dl,[bx] mov ax,0020h mov ds,ax mov [bx],dl inc bx loop copy mov ax,4c00h int 21h code ends end copy
5.将AX寄存器中的16位数分成四组,每组四位,然后把这四组数分别放在AL、BL、CL和DL中。
data segment s db 4 dup(?) ;占位,并清空 mov ax,0ffffhdata ends ;----------------------------------- progrnam segment assume cs:progrnam,ds:data begin:mov cl,4 ;ax逻辑右移四次 mov ch,4 lea bx,s X: mov dx,ax and dx,0fh ;逻辑与屏蔽高位 mov [bx],dl ;以字节形式将dl移入bx inc bx shr ax,cl ;逻辑右移 dec ch jnz X Y: mov dl,s ;依次移入相应寄存器内 mov cl,s+1 mov bl,s+2 mov al,s+3 ret progrnam ends end begin
6.从键盘输入一系列字符,以字符‘$’为结束符,然后对其中的非数字字符计数,并显示出计数结果。
`stack segment dw 100h dup(?) top label wordstack endsdata segment h1 db 'Please input a string: ','$' h2 db 'The number of the chars that is not digit:','$' crlf db 0dh,0ah,24hdata endscode segment assume cs:code,ds:data,ss:stack main proc far begin:mov ax,stack mov ss,ax lea sp,top mov ax,data mov ds,ax lea dx,h1 mov ah,9 int 21h mov cx,0input: mov ah,1 int 21h cmp al,'$' jz exit cmp al,30h jb count cmp al,39h jnb count jmp inputcount: inc cx jmp inputexit: lea dx,crlf mov ah,9 int 21h lea dx,h2 int 21h mov si,0 mov bl,10 mov ax,cxmem: div bl mov dl,ah mov dh,0 push dx inc si mov ah,0 cmp al,0 jnz mem prin: pop dx add dl,30h mov ah,2 int 21h dec si cmp si,0 jnz prin mov ah,4ch int 21Hmain endpcode ends end begin `
7.已知两个整数变量A和B,试编写完成下述操作的程序:
(1)若两个数中有一个数是奇数,则将奇数存入A中,偶数存入B中
(2)若两个数均为奇数,则两数分别加1,并存回原变量。
(3)若两个数均为偶数,则两变量不变。
code segment assume cs:code begin: mov ax,13 mov bx,12 mov cx,ax mov dx,bx xor ax,bx test ax,0001h ;A和B是否同时为奇数或偶数 jz next ;是 test bx,0001h jz return ;B为偶数,A为奇数,加1exchange:mov ax,dx ;A为偶数,B为奇数,交换 mov bx,cx jmp return next:test bx,0001h ;是否同为奇数 jz return ;同为偶数,不变 inc dx inc cx jmp exchange return:ret code ends end begin
8.比较两个字符串string1和string2所含的字符是否相同。若相同则显示‘true’,否则显示‘false’。
data segment string1 db 'i am a student' string2 db 'i am a student' string3 db 'true',0dh,0ah,'$' string4 db 'false',0dh,0ah,'$'data ends ;-------------------------- progrnam segment assume cs:progrnam,ds:datastart:push ds sub ax,ax push ax mov ax,data mov ds,ax mov es,ax begin:lea si,string1 lea di,string2 cld mov cx,string2-string1 repe cmpsb jne Y lea dx,string3 jmp print Y:lea dx,string4 print: mov ah,9 int 21h mov ax,4c00h int 21hprogrnam ends end start
9.编写无溢出除法的汇编子程序 。
这里所说的除法溢出并不是指分母为0而发生溢出的情况。我们以除数为8位的情况来说明,假设我们的被除数为65535(16位的最大值)存储在AX 中,除数为1,存储在CL中,然后执行除法指令: div CL。根据上面的说法,结果都是放在AX中的,余数为0,当然这没有问题,然而商为65535要放在AL中却是放不下的,因为AL能存放的最大值只为 255,所以此时就会发生溢出。我们可以看到65535/1 = 255,这显然与我位正常的除法结果不符。
如何解决这个溢出问题
既然我们知道了问题的根源,要解 决它就不困难了。为了统一而且不发生溢出,我们可以把所有的除法的商都用32位来保存,即所有的被除数都用32位,所有的除数都用16位,所有的商都用 32位,所有的余数都用16位来保存,就可以解决这个问题,因为一个数除以一个整数后,不可能大于其之前的值。而对于8位的除法,除数和被除数的高位全用 0补全即可。为了达到这个目的,我们就不能使用默认的除法指令div了,而需要我们写代码来实现我们自定义的除法。
自定义除法: X为除数,N为被除数,H代表X的高16位,L代表X的低16位,
int(H/N)和rem(H/N)代表着H除以N的商和余数
X/N = int(H/N)* 2^16 + [rem(H/N)* 2^16+L]/N
progrnam segment assume cs:progrnam mov ax,0ffffh mov cx,1 ;初始化进行测试 begin: cmp cx,0 je return ;除数不能为0 push bx push ax mov ax,dx mov dx,0 div cx ;执行H/N,商保存在ax中,余数在DX中 mov bx,ax ;把商保存 pop ax ;取出低位,执行rem(H/N)*2^16+L div cx ;执行[rem(H/N)*2^16+L]/N ,商保存在ax中 ,余数在dx中 mov cx,dx ;cx保存余数 mov dx,bx ;dx中保存高位除法的商 pop bx return:ret mov ax,4c00h int 21h progrnam ends end begin
10.编写一个程序,接受从键盘输入的10个十进制数字,输入回车符则停止输入,然后将这些数字加密后(用XLAT指令变换)存入内存缓冲区BUFFER。加密表为:
输入数字:0,1,2,3,4,5,6,7,8,9
密码数字:7,5,9,1,3,6,8,0,2,4
data segment number db 7,5,9,1,3,6,8,0,2,4 buffer db 10 dup(?)data ends ;-------------------------------------code segment assume cs:code,ds:data mov si,0 mov cx,10 lea bx,number input:mov ah,1 int 21h cmp al,0dh ;是否为回车符 jz return cmp al,30h ;比较是否是0~9,不是就重新输入 jb input cmp al,39h ja input xlat ;变换进行存储 mov buffer[si],al inc si loop input return:ret code ends end inputdata segment number db 7,5,9,1,3,6,8,0,2,4 buffer db 10 dup(?)data ends ;-------------------------------------code segment assume cs:code,ds:data mov si,0 mov cx,10 lea bx,number input:mov ah,1 int 21h cmp al,0dh ;是否为回车符 jz return cmp al,30h ;比较是否是0~9,不是就重新输入 jb input cmp al,39h ja input xlat ;变换进行存储 mov buffer[si],al inc si loop input return:ret code ends end input
11.编写一个子程序嵌套结构的程序模块,分别从键盘输入姓名及8个字符的电话号码,并以一定的格式显示出来。
主程序TELIST:A. 显示提示符“INPUT NAME:”;B. 调用子程序INPUT_NAME输入姓名;C. 显示提示符“INPUT A TELEPHONE NUMBER:”;D. 调用子程序INPHONE输入电话号码;E. 调用子程序PRINTLINE显示姓名及电话号码。子程序INPUT_NAME:A. 调用键盘输入子程序GETCHAR,把输入的姓名存放在INBUF缓冲区中;B. 把INBUF中的姓名移入输出行OUTNAME。子程序INPHONE:A. 调用键盘输入子程序GETCHAR,把输入的8位电话号码存放在INBUF缓冲区中;B. 把INBUF中的号码移入输出行OUTPHONE。子程序PRINTLINE:显示姓名及电话号码,格式为: NAME TEL. X X X XXXXXXXX
代码如下:
data segment tipname db 'input name:','$' tipnumber db 'input a telephone number:','$' inbuf db 12 dup(' ') crlf db 0dh,0ah,'$' outname db 16 dup(' ') outphone db 12 dup(' '),0dh,0ah,'$' info db 'name',12 dup(' '),'tel',0dh,0ah,'$'data ends;------------------------------------stack segment dw 100 dup(?) ;伪定义使得同一个变量具有不同的属性 string label word stack ends ;----------------------------------------progrnam segment main proc far assume cs:progrnam,ds:data,es:data,ss:stack start:mov ax,stack mov ss,ax mov sp,offset string push ds xor ax,ax push ax mov ax,data mov ds,ax mov es,ax begin: mov ah,09 ;输出提示字符串 mov dx,seg tipname mov ds,dx mov dx,offset tipname int 21h call input_name ;输入姓名 mov ah,09 ;输出提示字符串 mov dx,seg tipnumber mov ds,dx mov dx,offset tipnumber int 21h call input_number call printline ret main endp ;------------------------------------------ input_name proc near call getchar lea si,inbuf lea di,outname mov cx,12 ;设置计数器 cld ;设置方向为自增;movsb 与rep结合是传送字节,相当于 movs es:byte ptr[di],ds:[si] rep movsb ret input_name endp ;-----------------------------------------------input_number proc near call getchar lea si,inbuf lea di,outphone mov cx,12 cld rep movsb ret input_number endp ;------------------------------------------------getchar proc near mov al,20h mov cx,12 lea di,inbuf cld ;stosb这里是为了每一次输入一个字节存入相应的缓冲区 rep stosb mov cx,12 mov di,0 input:mov ah,1 int 21h cmp al,0dh jz return mov inbuf[di],al inc di loop input return: call disp_crlf ;输出回车符 ret getchar endp ;--------------------------------------printline proc near ;这里均是将所得的字符串进行输出 mov ah,09 mov dx,seg info mov ds,dx mov dx,offset info int 21h mov ah,09 mov dx,seg outname mov ds,dx mov dx,offset outname int 21h ret printline endp ;---------------------------------------disp_crlf proc near mov ah,09 mov dx,seg crlf mov ds,dx mov dx,offset crlf int 21h ret disp_crlf endp ;-----------------------------------------progrnam ends end start
12.试编写一个汇编语言子程序,要求将包含任意字符、以0结尾的字符串中的小写字母转换成大写字母。
data segment string db 'i am A stuDEnt',0hdata ends;------------------------------progrnam segment assume ds:data,cs:progrnamstart:push ds xor ax,ax mov ax,data mov ds,ax lea si,string push si begin: mov al,[si] ;判断是否为小写字母并进行转换 cmp al,0 je return cmp al,'a' jb print cmp al,'z' ja print ;如果不是小写字母直接进行输出 sub al,20h mov [si],alprint:push ds ;将字母进行输出 ;mov al,[si] mov dl,al mov ah,2 int 21h pop ds n:inc si jmp begin return: pop si pop ds mov ax,4c00h int 21hprogrnam ends end start
13.编写程序,将一个包含有20个数据的数组M分成两个数组:正数数组P和负数数组N,并分别把这两个数组中数据的个数显示出来。
data segment string1 db 0dh,0ah, 'positive number:','$' string2 db 0dh,0ah,'negative number:','$' array dw 1,2,3,4,5,6,7,8,-4,-8,-9,-6,-2,-8,8,12,18,-12,5,64 array1 dw 20 dup(?) ;存储正数数组 array2 dw 20 dup(?) ;存储负数数组 count1 db 0 count2 db 0 ;计数 CRLF DB 0dh,0ah,'$'data ends;----------------------------------progrnam segment main proc far assume ds:data,cs:progrnam s: push ds xor ax,ax push ax mov ax,data mov ds,ax begin:mov cx,20 ;循环次数 lea bx,array ;bx相当于数组的首地址 lea si,array1 lea di,array2 start:mov ax,[bx] cmp ax,0 ;是否为负数 js Y ;是负数 mov [si],ax ;存入正数数组 inc count1 add si,2 jmp short next Y: mov [di],ax inc count2 add di,2 next:add bx,2 loop start lea dx,string1 mov al,count1 call print lea dx,string2 mov al,count2 call print retmain endp ;--------------------------------------print proc near push ax ;al中存储计数值,要进行保存 mov ah,9 int 21h pop ax ;出栈,进行ASCII码调整 aam ;调整方式AH<-AL/10(商),AL<-AL%10 push ax add ah,30h ;变为0~9的ASCII码 mov dl,ah mov ah,2 int 21h pop ax add al,30h mov dl,al mov ah,2 int 21h lea dx,CRLF mov ah,9 int 21h ret print endp progrnam ends end s
14.设有10个学生的成绩分别是76,69,84,90,73,88,99,63,100和80分。试编制一个子程序统计60~69分,70~79分,80~89分,90~99分和100分的人数,分别存放到S6,S7,S8,S9和S10单元中。
data segment grade dw 76,69,84,90,73,88,99,63,100,80 count1 dw 0 count2 dw 0 count3 dw 0 count4 dw 0 count5 dw 0data ends;-----------------------------------------progrnam segment assume ds:data,cs:progrnam push ds xor ax,ax push ax mov ax,data mov ds,ax begin:mov cx,10 mov si,0 next:mov ax,grade[si] mov bx,10 div bl mov bl,al sub bx,6 sal bx,1 ;将(grade/10-6)×2就是 inc count1[bx] ;count1是首地址 add si,2 loop nextprogrnam ends end begin
15.输出空行
progrnam segment assume cs:progrnam begin:push cx push dx mov ax,3 ;这里对ax进行赋值,观察输出的结果 mov cx,ax print:mov dl,0dh mov ah,2 ;这是对与输出一个字符的bios的调用 int 21h ;print的功能就是输出空行,0dh为回车 mov dl,0ah ;0ah为换行 mov ah,2 int 21h loop print pop dx pop cx ;这一段程序是为了测试输出后的结果,主要母的是输出一个黄色的'*' mov ah,9 mov al,'*' mov bh,0 mov bl,0eh mov cx,1 int 10h retprogrnam ends end begin
- 反汇编常见代码
- 常见汇编代码
- u-boot 代码中常见汇编指令
- 常见语言反汇编入口代码
- u-boot 代码中常见汇编指令
- 常见语言反汇编入口代码
- u-boot 代码中常见汇编指令
- u-boot 代码中常见汇编指令
- U-Boot代码中常见汇编指令
- 常见汇编
- 汇编常见伪指令
- 汇编常见错误
- 汇编常见错误
- Android常见错误汇编
- AT汇编常见命令
- 汇编常见错误
- 汇编常见伪指令
- 常见的基本汇编书籍
- nginx安装配置
- vmware下安装Archlinux遇到的问题记录
- blueimp/jquery-File-Upload中文文档
- Java---微信公众号开发
- php
- 常见汇编代码
- 软件测试 (一) 软件测试方法大汇总
- 数据类型的位数
- 网络编程 java
- HTML的标准化
- Drupal 使用Nginx进行反向代理的配置
- Ceph RadosGW - Placement Targets
- 常用的树形菜单
- C# 委托事件的应用