• 汇编的基础


    原视频

    基础篇:1.1编程环境的安装

    打开DOSBox 0.74-3 Options.bat调整窗口大小

    windowresolution=1200x640
    output=ddraw
    
    • 1
    • 2
    mount c D:\masm
    c:
    debug
    
    • 1
    • 2
    • 3

    DEBUG

    用Debug的R命令查看、改变CPU寄存器的内容:
    用Debug的D命令查看内存中的内容:
    用Debug的E命令改写内存中的内容:
    用Debug的U命令将内存中的机器指令翻译成汇编指令
    用Debug的T命令执行一条机器指令:
    用Debug的A命令以汇编指令的格式在内存中写入一条机器指令。

    mov,add,sub

    mov ax,bx
    ax=bx
    add ax,bx
    ax+=bx
    sub ax,bx
    ax-=bx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    mul,div,and,or

    mul乘法指令

    因下面要用到,这里介绍一下mul指令,mul是乘法指令,使用mul做乘法的时候,
    注意以下两点。
    (1)两个相乘的数:两个相乘的数,要么都是8位,要么都是16位。如果是8位,一个默认放在AL中,另一个放在8位reg或内存字节单元中:如果是16位,一个默认在AX中,另一个放在16位reg或内存字单元中。
    (2)结果:如果是8位乘法,结果默认放在AX中:如果是16位乘法,结果高位默认在DX中存放,低位在AX中放。
    
    
    mul bl
    al*bl
    结果在ax
    
    mul bx
    ax*bx
    结果高位在DX 低位在AX
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    div除法指令

    (I)除数:有8位和16位两种,在一个reg或内存单元中。
    (2)被除数:默认放在AX或DX和AX中,如果除数为8位,被除数则为16位,
    默认在AX中存放:如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位。
    (3)结果:如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数:
    如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数。
    
    
    div bl
    ax/bl
    结果ah为余数 al为商
    
    div bx
    (dx*2^32+ax)/bx
    结果dx为余数 ax为商
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    and or

    (I)and指令:逻辑与指令,按位进行与运算。
    例如指令:
    mov al,01100011B
    and al,00111011B
    执行后:al=00100011B
    (2)or指令:逻辑或指令,按位进行或运算。
    例如指令:
    mov al,01100011B
    or al,00111011B
    执行后:al=01111011B
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    shl

    是逻辑左移指令,它的功能为

    (1)将一个寄存器或内存单元中的数据向左移位:
    (2)将最后移出的一位写入CF中
    (3)最低位用0补充。
    
    
    mov al,01001000b
    shl al,1
    执行后al=10010000b cf=0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    shr

    是逻辑右移指令,它和shl所进行的操作刚好相皮

    (1)将一个寄存器或内存单元中的数据向右移位:
    (2)将最后移出的一位写入CF中:
    (3)最高位用0补充。shr是逻辑右移指令,它和shl所进行的操作刚好相反
    
    
    mov al,10000001b
    shr al,1
    执行后:(al)=01000000b,CF=1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    dec inc neg xchg

    dec ax
    ax--
    inc ax
    ax+=
    neg ax
    ax取反
    xchg ax,bx
    ax与bx的值交换
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    int

     int指令是X86汇编语言中最重要的指令之一。它的作用是引发中断,调用“中断例程”(interrupt routine)。本文将介绍int指令的基本原理和应用,以及BIOS和DOS系统的中断例程。
    
    一、int指令的原理
    
    1,指令原型
    int n
    注:    
    1)n 表示中断号,也可以称为中断类型码。n是一个字节大小的正整数,范围为“0 - 255”。
    2)执行“int n”时,CPU从中断向量表中,找到第n号表项,修改CS和IP
    
        (IP)=(n*4),(CS)=(n*4+2)
    
    3)对8086PC,中断向量表指定放在内存地址0处(地址固定),共1024个字节。每个表项占两个字,低字存放偏移地址,高字存放段地址。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    ds寄存器,段地址,偏移地址,物理地址

    ds用来放段地址
    存放当前正在运行的程序代码所在段的段基值
    073f:0100
    段地址为073f
    偏移地址为0100
    物理地址为073f*16+0100
    
    给ds寄存器赋值
    mov ax,0100
    mov ds,ax
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    cs:ip

    基地址:偏移地址

    cs 为代码段寄存器,一般用于存放代码;
    通常和IP 使用用于处理下一条执行的代码
    
    • 1
    • 2

    jmp

    jmp bx
    将ip寄存器的值改为bx
    
    • 1
    • 2

    ss-sp pop push

    存储栈的地址
    ss-sp指向栈顶
    push寄存器
    :将一个寄存器中的数据入栈
    pop寄存器
    :出栈,用一个寄存器接收出栈的数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    -a
    073F:0100 mova×,1234
    073F:0103 push a×
    073F:0104 mov b×,5678
    073F:0107 push bx
    073F:0108 pop ax
    073F:0109 pop bx
    073F:010A
    
    sp=00fd
    sp=00fb
    sp=00f9
    
    073F:0100                       78 56 34 12 00 00 00
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    bp si di

    mov ax,[bx]
    mov ax,[si]
    mov ax,[si+1]
    mov ax,[si+bx]
    错误指令
    mov ax,[bx+bp]
    mov ax,[si+di]
    
    存放段地址的寄存器可以是默认的,比如:
    mov ax,[0]
    mov ax,[di]
    mova,[bx+8]
    mowa%,[bx+si]
    mov ax,[bx+si+B]
    等指令,段地址默认在ds中:
    mov ax,[bp]
    mov ax,[bp+8]
    mov ax,[bp+si]
    mov ax,[bp+si+8]
    等指令,段地址默认在ss中。
    
    
    (3)只要在[...]中使用寄存器bp,而指令中没有显性地给出段地址,段地址就默认在ss中。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    es 为扩展段寄存器; ss 为栈段寄存器,一般作为栈使用 和sp搭档;

    es 为扩展段寄存器;

    flag寄存器

    标志truefalseName(名称)命题
    OFOV (Overflow)NV (Not Overflow)0verflowFlag(是否溢出)存在溢出?
    SFNG(NeGative负的)PL(Plus正的)Sign Flag(结果的符号是正还是负)是负数(正数看做无符号)?
    ZFZR(Zero)NZ(Not Zero)Zero Flag(运算结果是否为0)是0?
    PFPE(Even偶数)Po(odd奇数)Parity Flag(结果中二进制位个数的奇偶性)是偶数个1?
    CFCY(Carry yes)NC(Not carry)Carry Flag(进位标志)有进位?
    DFDN (Down)UP(Up)Direction Flag(方向标志)si、di递减?

    adc

    adc ax,bx
    ax=ax+bx+CF
    
    • 1
    • 2

    sbb

    sbb ax,bx
    ax=ax-bx-CF
    
    • 1
    • 2

    cmp

    cmp是比较指令,cmp的功能相当于减法指令,只是不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。
    cmp ax,bx
    ax-bx
    
    如果(ax)=(bx)则(ax)-(bx)=0,所以:zf=1
    如果(ax)≠(bx)则(ax)-(bx)≠0,所以:zf=0
    如果(ax)(bx)则(ax)-(bx)既不必借位,结果又不为0,所以:cf=0并且zf=0
    如果(ax)≤(bx)则(ax)-(bx)既可能借位,结果可能为0,所以:cf=1或zf=1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    指令含义检测的相关标志位
    je等于则转移zf=1
    jb低于则转移cf=1
    ja高于则转移cf=0且zf=0
    cmp ax,bx
    je 073f:0106
    
    • 1
    • 2

    运行asm文件

    masm
    输入文件名
    link 文件名
    debug 文件名.asm
    
    • 1
    • 2
    • 3
    • 4

    循环语句loop

    loop指令的格式是:loop标号,CPU执行loop指令的时候,要进行两步操作,
    ①cx=cx-1:②判断cx中的值,不为零则转至标号处执行程序,如果为零则向下执行。
    下面例子中ax=2^12
    
    • 1
    • 2
    • 3
    assume cs:code
    code segment
      start:mov ax,2
    		mov cx,12
    		s:
    		 add ax,ax
    		 loop s
    		int 21H
    code ends
    end start
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    call ret

    call在执行时会先将下一条指令所对应的ip地址入栈,然后修改ip的值实现跳转, ret指令执行的时候,将ip地址pop出来进行跳转
    
    call s ;
    标号里面存放的是ip偏移地址 如果写成call 3H  
    那么意思就是跳转到CS:0003h这个位置
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    执行函数s
    
    • 1
    assume cs:code
    code segment
      start:mov ax,2
    		mov cx,12
    		call s
    		int 21H
    		s:
    		add ax,ax
    		loop s
    		ret
    code ends
    end start
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    call Far ptr retf

    ret和call配套使用,retf和call Far ptr 配套使用

    可以通过标号(函数名称)之间数值相减计算函数体代码所占用的内存空间大小

    retf需要配合栈进行使用,当程序执行到retf这条指令时,会连续从栈中pop两次数据,第一次的数据赋值给CS,第二次的数据赋值给IP,那么如果我们想要跳转到指定的指令,需要将该指令的段地址和偏移地址分别push进栈中

    stack segment
    	db 128 dup(0)
    stack ends
    
    code segment
    	start:
    		mov ax,stack
    		mov ss,ax
    		mov sp,128
    		
    		mov ax,0710H ;指定段地址
    		push ax
    		mov ax,0003H ;指定偏移地址
    		push ax
    		
    		retf ;程序跳转到0710:0003H这个位置
    code ends
    end start
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    内存地址    机器码                         汇编指令
    1000:0      b8 00 00                      mov ax,0
    1000:3      9a 09 00 00 10            call far ptr s
    1000:8      40                                inc ax
    1000:9      58                             s:pop ax
                                                         										add ax,ax
                                                         										pop bx
                                                         										add ax,bx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    为什么ax会是1010?详细解答
    
    执行指令先要读入到指令缓冲区中
    读进去以后IP已经指向下一条指令了
    call far ptr执行了push cs,push ip,jmp far ptr
    这么指行的话call far ptr s的cs:1000,ip:8
    把cs先扔进栈,后扔ip
    那么到了s:pop ax这个时候应该是ip先出来,所以ax=8
    接着执行add ax,ax=6
    接着pop bx,现在bx=1000
    然后执行add ax,bx
    那么就是ax=1010H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    代码段、数据段、栈段、dup指令

    assume cs:codesg,ds:data,ss:stack
    MASM内部以数基的个数定义了多种数据类型
    BYTE,db,8位
    WORD,dw,16位
    DWORD,dd,32位
    QWORD,dq,64位
    
    db 10 dup (0)
    初始化10个值为0的空间
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    assume cs:codesg,ds:data,ss:stack
    data segment
    		dw 123H,456H,789H,OabcH,OdefH
    		db 3 dup(1,2,3)
    		db 3 dup ('abc,'def)
    data ends
    stack segment
    		db 10 dup (0)
    stack ends
    codesg segment
    		start:
    		dw 'hellow rold'
    		mov ax,3
    		mov cx,11
    		call s
    		inc bx
    		inc bx
    		int 21H
    		add ax,ax
    		loop s
    codesg ends
    end start
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    offset

    操作符offset在汇编语言中是由编译器处理的符号,它的功能是取得标号的偏移地址。比如下面的程序:
    assume cs:codesg
    codesg segment
    	start:mov ax,offset start;相当于mov ax,0
    		s:mov ax,offset s;相当于mov ax,3
    codesg ends
    end start
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    jmp short s jmp far s

    跳转到s位置
    jmp short s 
    机器码显示距离
    jmp far s
    机器码显示距离地址
    
    • 1
    • 2
    • 3
    • 4
    • 5

    jmp dword ptr

    功能:从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址。
    内存单元地址可用寻址方式的任一格式给出。
    比如,下面的指令:
    mov ax,0123H
    mov ds:[0],ax
    mov word ptr ds:[2],0
    jmp dword ptr ds:[0]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    数组

    data1    dd 0, 1, 2, 4                 ;
    相当于 int data1[] = { 0, 1, 2, 3 };
    data1[1]是内存地址+1(不论什么类型都是1个字节)
    
    • 1
    • 2
    • 3

    lea

    lea是“load effective address”的缩写
    简单的说,lea指令可以用来将一个内存地址直接赋给目的操作数
    例如:lea eax,[ebx+8]就是将ebx+8这个值直接赋给eax,而不是把ebx+8处的内存地址里的数据赋给eax。
    而mov指令则恰恰相反,例如:mov eax,[ebx+8]则是把内存地址为ebx+8处的数据赋给eax。
    
    • 1
    • 2
    • 3
    • 4

    5.11输出hello world

    assume cs:codesg,ds:data,ss:stack
    data segmeNT
    	str db 'hello world','$'
    data ends
    stack segment
    	db 10 dup (0) 
    stack ends
    codesg SEgment
    	start:	
    		mov ax,data
    		mov ds,ax
    		lea dx,str		
    		mov ah,9
    		int 21H
    
    		mov ah,4cH
    		int 21H
    codesg ends
    end start
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    5.12字符串转大写

    assume cs:codesg,ds:data,ss:stack
    data segmeNT
    	str db 'hello world','$'
    data ends
    stack segment
    	db 10 dup (0) 
    stack ends
    codesg SEgment
    	start:	
    	mov ax,data
    	mov ds,ax
    	
    	mov bx,0
    	mov cx,11
    	s:
    		mov al,[bx]
    		and al,1011111B
    		mov [bx],al
    		inc bx
    		loop s
    		
    		;mov dx,offset str
    		lea dx,str		
    		mov ah,9
    		int 21H
    
    		mov ah,4cH
    		int 21H
    codesg ends
    end start
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    5.13字符串转小写

    assume cs:codesg,ds:data,ss:stack
    data segmeNT
    	str db 'hello world','$'
    data ends
    stack segment
    	db 10 dup (0) 
    stack ends
    codesg SEgment
    	start:	
    	mov ax,data
    	mov ds,ax
    	
    	mov bx,0
    	mov cx,11
    	s:
    		mov al,[bx]
    		or al,0100000B
    		mov [bx],al
    		inc bx
    		loop s
    		
    		;mov dx,offset str
    		lea dx,str		
    		mov ah,9
    		int 21H
    
    		mov ah,4cH
    		int 21H
    codesg ends
    end start
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    5.14求数组最小值

    assume cs:codesg,ds:data,ss:stack
    data segmeNT
    	str db 'hello world','$'
    data ends
    stack segment
    	db 10 dup (0) 
    stack ends
    codesg SEgment
    	start:	
    	mov ax,data
    	mov ds,ax
    	
    	mov bx,0
    	mov cx,11
    	mov ah,0FFH
    	s:
    		mov al,[bx]
    		cmp ah,al
    		jna s1
    		mov ah,al
    	s1:
    		mov [bx],al
    		inc bx
    		loop s
    		
    		;mov dx,offset str
    		lea dx,str		
    		mov ah,9
    		int 21H
    
    		mov ah,4cH
    		int 21H
    codesg ends
    end start
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    5.15求数组最大值

    assume cs:codesg,ds:data,ss:stack
    data segmeNT
    	str db 'hello world','$'
    data ends
    stack segment
    	db 10 dup (0) 
    stack ends
    codesg SEgment
    	start:	
    	mov ax,data
    	mov ds,ax
    	
    	mov bx,0
    	mov cx,11
    	mov ah,0
    	s:
    		mov al,[bx]
    		cmp ah,al
    		jnb s1
    		mov ah,al
    	s1:
    		mov [bx],al
    		inc bx
    		loop s
    		
    		;mov dx,offset str
    		lea dx,str		
    		mov ah,9
    		int 21H
    
    		mov ah,4cH
    		int 21H
    codesg ends
    end start
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    5.21数组求和

    assume cs:code,ds:data,ss:stack
    data segment 
    	arr db 1,2,3,4,10,20,30,40
    	res db 8 dup (0)
    data ends
    
    stack segment 
    	
    	db 100 dup (0)
    stack ends
    
    code segment 
    	start:
    		mov ax,data
    		mov ds,ax
    		
    		mov bx,0
    		mov cx,8
    		for:
    			add al,arr[bx]
    			inc bx
    		loop for
    			
    		mov ax,4c00H
    		int 21
    code ends
    end start
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    5.22拷贝数组

    assume cs:code,ds:data,ss:stack
    data segment 
    	arr db 1,2,3,4,10,20,30,40
    	res db 8 dup (0)
    data ends
    
    stack segment 
    	
    	db 100 dup (0)
    stack ends
    
    code segment 
    	start:
    		mov ax,data
    		mov ds,ax
    		
    		mov bx,0
    		mov cx,8
    		for:
    			mov al,arr[bx]
    			mov ds:res[bx],al
    			inc bx
    		loop for
    			
    		mov ax,4c00H
    		int 21
    code ends
    end start
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    5.23用si,di翻转数组

    assume cs:code,ds:data,ss:stack
    data segment 
    	arr db 1,2,3,4,10,20,30,40
    	res db 8 dup (0)
    data ends
    
    stack segment 
    	
    	db 100 dup (0)
    stack ends
    
    code segment 
    	start:
    		mov ax,data
    		mov ds,ax
    		
    		mov si,0
    		mov di,7
    		mov cx,8
    		for:
    			mov al,arr[si]
    			mov ds:res[di],al
    			inc si
    			dec di
    		loop for
    			
    		mov ax,4c00H
    		int 21
    code ends
    end start
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    5.31用栈翻转数组

    assume cs:code,ds:data,ss:stack
    data segment 
    	arr dw 1111H,2222H,3333H,4444H,5555H,6666H,7777H,8888H
    	res db 800 dup (0)
    data ends
    
    stack segment 
    	db 1000 dup (0)
    stack ends
    
    code segment 
    	start:
    		mov ax,data
    		mov ds,ax
    		mov ax,stack
    		mov ss,ax
    		mov sp,100
    
    		mov bx,0
    		mov cx,8
    		for:	
    			push ds:arr[bx]
    			add bx,2
     		loop for
    
    		mov bx,0
    		mov cx,8
    		for1:	
    			pop ds:arr[bx]
    			add bx,2
     		loop for1
    
    			
    		mov ax,4c00H
    		int 21
    code ends
    end start
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    5.32动态规划求斐波那契数列

    assume cs:code,ds:data,ss:stack
    data segment 
    	arr dw 1H,1H,100 dup (0)
    	res db 800 dup (0)
    data ends
    
    stack segment 
    	db 100 dup (0)
    stack ends
    
    code segment 
    	start:
    		mov ax,data
    		mov ds,ax
    		mov ax,stack
    		mov ss,ax
    		
    		mov bx,4
    		mov cx,30
    		for :
    			mov dx,0
    			add dx,ds:arr[bx-2]
    			add dx,ds:arr[bx-4]
    			mov ds:arr[bx],dx
    		add bx,2
    		loop for
    			
    		mov ax,4c00H
    		int 21
    code ends
    end start
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    5.41循环把二维矩阵某一列转大写

    assume cs:codesg,ds:data,ss:stack
    data segmeNT
    	str db 'aaaaabbbbbccccc '
    	db 'aaaaabbbbbccccc '
    	db 'aaaaabbbbbccccc '
    	db 'aaaaabbbbbccccc ','$'
    
    data ends
    stack segment
    	db 10 dup (0) 
    stack ends
    codesg SEgment
    	start:	
    	mov ax,data
    	mov ds,ax
    	
    	mov bx,0
    	mov cx,4
    		for:
    			mov al,ds:str[bx+5]
    			and al,11011111B
    			mov ds:str[bx+5],al
    	add bx,16
    	loop for
    		
    	lea dx,str		
    	mov ah,9
    	int 21H
    
    	mov ah,4cH
    	int 21H
    codesg ends
    end start
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    5.42二重循环把指定矩形转大写

    assume cs:codesg,ds:data,ss:stack
    data segmeNT
    	str db 'aaaaabbbbbccccc '
    	db 'aaaaabbbbbccccc '
    	db 'aaaaabbbbbccccc '
    	db 'aaaaabbbbbccccc ','$'
    
    data ends
    stack segment
    	db 10 dup (0) 
    stack ends
    codesg SEgment
    	start:	
    	mov ax,data
    	mov ds,ax
    	
    	mov bx,0
    	mov cx,4
    	for:
    	      mov dx,cx
    		mov si,0
    		mov cx,5
    		for1:
    			mov al,ds:str[bx+si]
    			and al,11011111B
    			mov ds:str[bx+si],al
    		inc si
    		loop for1
    	     mov cx,dx
    	add bx,16
    	loop for
    		
    	lea dx,str		
    	mov ah,9
    	int 21H
    
    	mov ah,4cH
    	int 21H
    codesg ends
    end start
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    5.51冒泡排序

    assume cs:codesg,ds:data,ss:stack
    data segmeNT
    	arr db 0A2H,24H,07H,3AH,1BH,0F1H,3BH,25H,81H
    
    data ends
    stack segment
    	db 10 dup (0) 
    stack ends
    codesg SEgment
    	start:	
    	mov ax,data
    	mov ds,ax
    	
    	
    	mov bx,0
    	mov cx,8
    	for:
    	      mov dx,cx
    		mov si,8
    		mov cx,8
    		sub cx,bx
    		for1:
    			mov ah,ds:arr[si]
    			mov al,ds:arr[si-1]
    			cmp ah,al
    			jnb all
    				xchg ah,al
    				mov ds:arr[si],ah
    				mov ds:arr[si-1],al				
    	
    			all:
    				
    		dec si
    		loop for1
    	     mov cx,dx
    	add bx,1
    	loop for
    
    	mov ah,4cH
    	int 21H
    codesg ends
    end start
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    5.61十进制转16进制

    assume cs:codesg,ds:data,ss:stack
    data segmeNT
    	str db '00012345','$'
    data ends
    stack segment
    	db 10 dup (0) 
    stack ends
    codesg SEgment
    	start:	
    		mov ax,data
    		mov ds,ax
    
    		mov bx,0
    		mov cx,8
    		mov ax,0
    		s:
    			mov dx,ax
    			shl ax,1
    			shl ax,1	
    			shl ax,1
    			shl dx,1
    			add ax,dx
    ;乘10
    
    			add al,str[bx]
    			adc ah,0
    			sub ax,30H		
    		
    			inc bx 
    			loop s
    	
    
    
    
    		mov ah,4cH
    		int 21H
    codesg ends
    end start
    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    5.61十进制转16进制并输出

    assume cs:codesg,ds:data,ss:stack
    data segmeNT
    	str db '00002333','$'
    	res db '0000','$'
    data ends
    stack segment
    	db 100 dup (0) 
    stack ends
    codesg SEgment
    	start:	
    		mov ax,data
    		mov ds,ax
    		mov ax,stack
    		mov ss,ax		
    		mov sp,10
    		mov si,4
    
    		mov bx,0
    		mov cx,8
    		mov ax,0
    		s:
    			mov dx,ax
    			shl ax,1
    			shl ax,1	
    			shl ax,1
    			shl dx,1
    			add ax,dx
    ;乘10
    
    			add al,str[bx]
    			adc ah,0
    			sub ax,30H		
    		
    			inc bx 
    			loop s
    		
    ;ax=3039
    	
    		mov cx,4
    		l:
    			mov dx,ax
    			and dx,0FH
    			add dx,30H
    			cmp dx,3AH
    			jb s1
    			add dx,7H
    ;求出3039的ASCII码,push
    		s1:
    			dec si
    			mov ds:res[si],dl
    			shr ax,1
    			shr ax,1
    			shr ax,1
    			shr ax,1
    			loop l
    
    		;mov dx,offset res
    	 	lea  dx,res
    		mov ah,9
    		int 21H
    
    		mov ah,4cH
    		int 21H
    codesg ends
    end start
    
    
    
    
    
    
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
  • 相关阅读:
    统一观测丨使用 Prometheus 监控 SQL Server 最佳实践
    Docker Tutorial
    CMMI认证多少钱?
    用 Visual Studio 调试器中查看内存中图像
    OpenWRT搭建个人web站点并结合内网穿透实现公网远程访问
    offer
    一个合格的后端开发总要经历一次死锁吧
    leetcode — JavaScript专题(八):间隔取消、使用方法链的计算器、判断对象是否为空、记忆函数 II、设计可取消函数
    【audio】alsa pcm音频路径
    verilog语言中条件编译ifdef的使用和例子
  • 原文地址:https://blog.csdn.net/fanlangke/article/details/130864760