快捷搜索:

您的位置:澳门新葡4473网站 > 项目 > 暂存

暂存

发布时间:2020-01-16 23:45编辑:项目浏览(106)

    code segment
    assume cs:code,ds:code,es:code,ss:code
    org 100h
    start:
    jmp begin
    buf db 80 dup(0)
    rmov: ;本函数用于右移存储器内容4个字节,需挤进去的内容为bx,dx,在内存中顺序为bl bh dl dh,si为内存起始地址,结束符为$
    push ax
    push si
    mov di,si
    mlp1:
    mov al,[si]
    cmp al,'$'
    jz mlp3
    cmp dl,[si+2]
    jb mlp2
    mov di,si
    mlp2:
    add si,4
    jmp mlp1
    mlp3:
    mov cx,si
    sub cx,di
    mov di,si
    add di,4
    std
    mlp4:
    lodsb
    stosb
    loop mlp4
    mov [si],bx
    mov [si+2],dx
    pop si
    pop ax
    ret

    # 常见汇编代码 #

    begin:
    mov bx,2020h
    mov dx,bx
    mov si,offset buf

    1. 编写程序:比较AX,BX,CX中带符号数的大小,将最大的数放在AX中

    code ends
    end start

            code segment

            assume cs:code

            mov ax,32

            mov bx,74

            mov cx,23

            sort: 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,4c00h

            code 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:ret

        code 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,0ffffh

        data 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  word

        stack ends

        data segment

                h1  db  'Please input a string: ','$'

                h2  db 'The number of the chars that is not digit:','$'

              crlf  db 0dh,0ah,24h

        data  ends

        code  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,0

        input:    mov    ah,1

                int    21h

                cmp    al,'$'

                jz      exit

                cmp    al,30h

                jb      count

                cmp    al,39h

                jnb    count

                jmp    input

        count:  inc    cx

                jmp    input

        exit:  lea    dx,crlf

                mov    ah,9

                int    21h

                lea    dx,h2

                int    21h

                mov    si,0

                mov    bl,10

                mov    ax,cx

        mem:    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    21H

        main    endp

        code    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为奇数,加1

        exchange: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:data

        start: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 21h

        progrnam 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 input

        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 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',0h

        data ends

        ;------------------------------

        progrnam segment

            assume ds:data,cs:progrnam

        start: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],al

        print: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 21h

        progrnam 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

                ret

        main 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 0

        data 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 next

        progrnam 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

                ret

        progrnam ends

                end begin

    16.冒泡排序

    ASSUME CS:CODE,DS:DATA

    DATA SEGMENT

            BUF DB 12, 32, -2, 4, 0    ; NUMBER ARRAY BUFFER

            CNT DB $-BUF              ; COUNT FOR BUFFER

    DATA ENDS

    CODE SEGMENT

    START:  MOV AX, DATA

            MOV DS, AX                  ; DATA SEGMENT

            MOV SI, OFFSET BUF          ; BUFFER INDEX

            MOV CL, CNT                ; LOOP COUNT

            DEC CL

            MOV CH, 0

    OUTER:                              ; OUTER LOOP

            MOV AL, [SI]                ; BUF[SI]

            PUSH CX

            MOV DI, SI                  ; BUFFER INDEX

    INNER:                              ; INNER LOOP

            INC DI                      ; DI = SI + 1

            MOV DL, [DI]                ; BUF[DI]

            CMP AL, DL                  ; IF (BUF[SI] > BUF[DI])

            JLE CONT                    ;

            XCHG AX, DX                ; SWAP (BUF[SI], BUF[DI])

            MOV [SI], AL

            MOV [DI], DL

    CONT:  LOOP INNER                  ; CONTINUE

            POP CX

            INC SI

            LOOP OUTER

            MOV AH, 4CH

            INT 21H

    CODE ENDS

    END STA

    本文由澳门新葡4473网站发布于项目,转载请注明出处:暂存

    关键词:

上一篇:没有了

下一篇:没有了