@guoxs
2016-06-11T08:02:03.000000Z
字数 1517
阅读 2064
汇编语言
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0cbah,0987h
mov bx,0
mov ax,0
s: add ax,cs:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
code ends
end
程序第一行中的“dw"的含义是定义字型数据,即为“define word”。
用dw定义的数据处于代码段的最开始,所以偏移地址是0。程序运行时,它们的地址就是:CS:0 CS:2 CS:4...
使用debug -u 查看:
发现在代码段的开头看到一些奇怪的代码,其实这是dw中数据对应的代码。从第16个字节开始才是汇编语言对应的机器码。
要运行这段代码,需要将IP设置为0010,跳过数据段。
这样做比较麻烦,还有一个较为简单的方法:
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0cbah,0987h
start mov bx,0
mov ax,0
s: add ax,cs:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
code ends
end start
添加
start
程序入口标记。程序在编译连接后,由end start
指明程序的入口,被转化为一个入口地址,储存在可执行文件的描述信息中。该程序中偏移地址部分为:10H。当程序被夹在到内存时,加载者从程序的可执行文件的描述信息中读到程序的入口地址,设置CS:IP。
有了这种方法,就可以这样安排程序的框架:
assume cs:code
code segment
...
...
数据
...
...
start:
...
...
代码
...
...
code ends
end start
将上一个程序的数据逆序存放:
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0cbah,0987h
;用dw定义16个字型数据,在程序加载后,将取得16个字的内存空间
;存放16个数据,在后面的程序中当做栈来使用
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
start mov ax,cs
mov ss,ax
mov sp,30h ;设置栈顶ss:sp指向cs:30
mov bx,0
mov cx,8 ;循环8次
s: push cs:[bx]
add bx,2
loop s ;以上将代码段单元中的8个字型数据依次入栈
mov bx,0
mov cx,8
s0: pop sc:[bx]
add bx,2
loop s0 ;出栈
mov ax,4c00h
int 21h
code ends
end start
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends
stack segment
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack ends
code segment
start mov ax,stack
mov ss,ax
mov sp,20h ;设置栈顶ss:sp指向stack:20
mov ax,data
mov ds,ax ;ds指向data段
mov bx,0 ;ds:bx指向data段中的第一个单元
mov cx,8 ;循环8次
s: push cs:[bx]
add bx,2
loop s ;以上将代码段单元中的8个字型数据依次入栈
mov bx,0
mov cx,8
s0: pop sc:[bx]
add bx,2
loop s0 ;出栈
mov ax,4c00h
int 21h
code ends
end start