汇编(八)[bx] 、Loop指令

5.1[bx]

  • [bx]是什么?

    • 实际上debug的语法和masm编译的语法是不一样的
    • 如果直接使用 mov ax, [0] 是不行的,编译器会把它看做 mov ax, 0
    • 需要使用bx, 比如 mov bx, 0, mov ax, [bx]的形式
    • mov ax, [bx]

      • 功能:将bx中存在的数据作为一个偏移地址EA,段地址SA默认在ds中, 将SA:EA处的数据送入ax中
  • mov ax, 2000H
    mov ds, ax
    mov bx, 1000H
    mov ax, [bx]
    inc bx
    inc bx
    mov [bx], ax
    inc bx
    inc bx
    mov [bx], ax
    inc bx
    mov [bx], al
    inc bx
    mov [bx], al
  • 内存中的情况

    • 2000:1000 = BE
    • 2000:1001 = 00
  • 上述程序分析:

    1. 先看一下前三条指令

      mov ax, 2000H

      Mov ds, ax

      Mov bx, 1000H

      • 三条指令执行后:

        ds=2000
        
        bx=1000
        
    2. 再看第四条指令:

      mov ax, [bx]

      • 将内存中2000:1000处的字型数据送入ax中, 结果ax=00be
    3. inc bx inc bx, inc 表单自增, 执行后bx=1002
    4. mov [bx], ax

      • 将ax中的值送入 ds:bx=2000:1002中
      • ax == 00be,

    5.2 Loop指令

  • (x)的应用,比如:

    1. ax中的内容为0010, 我们可以用这样描述:(ax)= 0010
    2. 2000:1000 处的内容为0010, 我们可以这样来描述(21000)=0010
    3. 对于mov ax,[2]的功能, 我们来描述: (ax)=((ds)16+2)
    4. 对于mov[2], ax的功能,我们可以这样来描述:((ds)16+2)=(ax)
    5. add ax, bx的功能:(ax)=(ax)+(bx)
    6. push ax的功能,我么可以这样描述:
  • idata表示常量

    1. mov ax, [idata]就代表mov ax,[1], mov ax, [2]等
  • 指令的格式:

    • loop 标号,CPU执行loop指令的时候, 要进行两步操作

      1. (cx)=(ax)- 1
      2. 判断cx中的值, 不为零则转到标号处执行程序,否则向下执行
    • 从上述中。我们可以看到 cx中的值影响执行结果
    • 通常我们用loop指令来实现循环功能, cx中存放循环次数
  • loop具体应用:

    • 编程计算2的2次方,结果放在ax中
    • assume cs:code
      code segment
          mov ax, 2
          add ax, ax
          
          mov ax, 4c00H
          int 21H
          
      code ends
      end
    • 计算2的三次方

      assume cs:code
      code aegment
          mov ax, 2
          add ax, ax
          add ax, ax
          
          mov ax, 4c00H
          int 21H
      code ends
-   计算2的12次方

-   ```assembly
    assume cs:code
    code segment
        mov ax, 2
        ; 做11次add ax,ax
        mov cx, 11
        s:add ax, ax
        loop s
        mov ax, 4c00H
        int 21H
    code ends
    end

    -   标号:

1.  在汇编语言中,标号就代表了一个地址, 此程序中一个标号它实际上表示了一个地址, 这个地址处有一条指令:add ax, ax

2.  Loop s

    1.  (cx)=(cx)-1
    2.  判断cx中的值, 不为0则转至标号s所表示的地址处执行, 如果为0,则执行下一条指令

3.  一下三条指令

    mov cx, 11

    S:add ax, ax

    Loop s

    -   执行loop时, 首先要将(cx)- 1 若不为0 这继续执行  add ax, ax, 所以利用cx来控制add ax, ax的执行次数

-   cx和loop指令配合实现循环功能的三个要点

    1.  在cx中存放循环次数
    2.  loop指令中的标号所标识地址要在前面
    3.  要循环执行的程序段, 要写在标号和loop指令中间

-   用加法计算123*236, 结果放在ax中

-   ```assembly
    assume cs:code
    code segment
mov ax, 0
mov cx, 123
s:add ax, 236
loops
     
mov ax, 4c00H
int 21H
    code ends
    end

5.3 在debug中用loop指令实现的循环过程

  • 首先,我们将它编辑为源程序文件, 文件名定义为p3.asm, 对齐进行编译链接后生p3.exe, 然后再用debug对p3.exe中的程序进行跟踪
  • 如果是循环比较多 可以使用debug的g指令调到指定地址, 跳过循环执行过程

5.4 debug和汇编编译器masm对指令的 不同处理

  • debug指令
  • mov ax, 2000H
    mov ds, ax
    mov al, [0]
    mov bl, [1]
    mov cl, [2]
    mov dl, [3]
  • masm汇编程序
  • assume cs:code
    code segment
        mov ax, 2000H
        mov ds, ax
        mov bx, 0
        mov al, [bx]
        mov bx, 1
        mov bl, [bx]
        mov bx, 2
        mov cl, [bx]
        mov bx, 3
        mov dl, [bx]
        
        mov ax, 4c00H
        int 21h
    code ends
    end
  • 上面说在汇编程序中不能直接写[2]这种格式,但是加上段地址也可以实现
  • assume cs:code
    code aegment
        movv ax, 2000H
        mov ds, ax
        mov al, ds:[0]
        mov bl, ds:[1]
        mov cl, ds:[2]
        mov dl, ds:[3]
        
        mov ax, 4c00H
        int 21H
    code ends
    end
上一篇:思考设计SQL优化方案


下一篇:解读联想预装程序LSC的三个CVE高危漏洞