第六章总结

在代码段中使用数据

dw:在程序中定义字型数据,

暂且把书上的例子当作dw的用法和在代码段中使用数据例子吧

 1 assume cs:code
 2 code segment
 3    dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
 4    mov ax,0
 5    mov cx,8
 6    mov bx,0
 7    s:add ax,cs:[bx]
 8    add bx,2
 9    loop s
10  
11    mov ax,4c00h
12    int 21h
13 code ends
14 end

在这个例子中,CS:0到CS:10是dw定义的8个数据,而在11到25为程序执行的代码。

可以在debug中用u和d查看,考虑到这里不是实验,就不截图了。

cx的初值为26h,说明程序代码的到25h结束。

(老师上课多次强调:精确的反汇编是u ip的值 到cx-1)(也可写作 ip cx-1)

故用u命令可写为,-u 0010 0025

在该程序中由于IP初始值为0,需在debug中用r改动IP的初值为10h。所以较为不便。

注:db,dw,dd

除了dw 也可以用db和dd来定义数据

db定义字节类型变量,一个字节数据占1个字节单元,每次读取数据,读完一个偏移量加1 。

dw定义字类型变量,一个字数据占2个字节单元,每次读取数据,读完一个偏移量加2。

dd定义双字类型变量,一个双字数据占4个字节单元,每次读取数据时,读完一个偏移量加4。

assume cs:code
code segment
    dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
start:
    mov ax,0
    mov cx,8
    mov bx,0
    s:add ax,cs:[bx]
    add bx,2
    loop s
    
    mov ax,4c00h
    int 21h
code ends
end start;end的用法二,指明执行start段的代码,可以通知编译器程序的入口所在

 

end的用法:

end 后什么也没有:程序运行到此结束

end 后加标号:标号为程序的入口点(标号相当于一个地址,而程序从标号处开始运行)

 

在代码段中使用栈

 

 1 assume cs:codesg
 2 codesg segment
 3     dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
 4     dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;dw 16 dup(0) 重复定义16个内存单元
 5
6
start: 7 mov ax,cs 8 mov ss,ax 9 mov sp,30h ;设置ss,sp 10 11 mov bx,0 12 mov cx,8 13 s: push cs:[bx] 14 add bx,2 15 loop s;将0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h入栈 16 17 mov bx,0 18 mov cx,8 19 s0: pop cs:[bx] 20 add bx,2 21 loop s0;将栈中的8个数据弹出到0----15单元中 22 23 mov ax,4c00h 24 int 21h 25 codesg ends 26 end start

1在debug中运行的时候,我们可以发现,cs:0-cs:0f是16给字节数据,cs:10-cs:2f是16个值为0的字节数据,在运行的过程中作为栈段

cx的值为58,精确的反汇编为 u 30 57(具体的截图可参见第六章的实验)

代码、数据、栈使用不同的段

在masm for windows 中默认的代码如下

 1 DATAS SEGMENT
 2     ;此处输入数据段代码  
 3 DATAS ENDS
 4 
 5 STACKS SEGMENT
 6     ;此处输入堆栈段代码
 7 STACKS ENDS
 8 
 9 CODES SEGMENT
10     ASSUME CS:CODES,DS:DATAS,SS:STACKS    ;用asssume 将逻辑段和段寄存器关联起来;
11 START:
12     MOV AX,DATAS
13     MOV DS,AX
14     ;此处输入代码段代码
15     MOV AH,4CH
16     INT 21H
17 CODES ENDS
18     END START

在8086cpu中可以通过使用多个段,解决长度不能超过64KB的问题(一个段最长64KB)

注意点:

用伪指令segment和ends定义逻辑段。

用asssume 将逻辑段和段寄存器(ds ss sp )关联起来;

段名称代表段地址,是常数,不能直接送入段寄存器。(先送入ax)

ES附加段寄存器,可以将其作为,其他任意的段寄存器。

 

posted @ 2018-11-19 19:33  20171308085  阅读(156)  评论(0编辑  收藏  举报