汇编

在 win7 64位下学习汇编,无法使用 debug 和 masm,可以利用 DosBox 这个软件。

DosBox 是一个 DOS 模拟程序,由于它采用的是 SDL 库,所以可以很方便的移植到其他的平台,支持 Windows、Linux、Mac OS X、Android 、webOS等系统。

1、先下载好 debug 和 masm ,解压到 d:\masm 目录下。

2、运行 DOSBox 后,我们可以看到Z : \ >,这是 DOSBox 里的虚拟盘,使用 mount 命令将 d:\masm 挂载到虚拟的 d 盘: mount d d:\masm

3、使用 "d:" 命令进入虚拟 d 盘,即可运行 debug 和 masm 程序。

可以通过配置 dosbox-0.74.conf 文件(或者通过开始菜单中的 DosBox 0.74 -> Options -> DosBox 0.74 Options 找到),在打开的文本末尾会找到 [autoexec] ,在它之后加上:

mount d d:\masm
set PATH=Z:;d: d:
cd source

这样就不需要每次进入 DosBox 都要重新配置了,并且设置了环境变量,可以在代码目录直接进行编译和链接了。

 

radasm 是一款汇编语言的 IDE,很好用,但是只能在 32 位系统下运行。官网下载只是一个编辑器,不带编译汇编功能,可以从网上下载整合好OD、masm 的汉化版,安装好之后,如果配置下 masm 的环境变量,“选项"——>"环境变量"——>将 PATH 设置成如 C:\RadASM\masm32\bin; 即可。

 

linux 下可以使用 objdump 将二进制文件反汇编,如  objdump -d test1 

 

Hello,World!

windows 版:

data    segment                ;数据段
hello    db    'Hello,World!$',0
data    ends

code    segment                ;代码段
    assume    cs:code,ds:data
start:                    ;入口
    mov    ax,data
    mov    ds,ax
    lea    dx,hello
    mov    ah,9h
    int    21h
    mov    ah,4ch
    int    21h

code    ends

end start            ;标志入口点

 

linux 版:

.section .data
msg: .ascii "Hello,World!\n"
len= . -msg

.section .text
#.globl main
.globl _start
#main:
_start:
    movl $4,%eax
    movl $1,%ebx
    movl $msg,%ecx
    movl $len,%edx
    int $0x80
    movl $1,%eax
    movl $0,%ebx
    int $0x80

使用 gcc hello.s 会编译错误,是因为用cc编译的话_start这个符号已经有定义了,这个是c runtime入口,cc编译的C程序的真正开始位置是_start symbol,这个_start在它初始化运行环境后调用main,因此你需要使用as编译这个汇编程序,因为gcc已经把_start占用了,如果非要用gcc可以使用gcc -nostdlib hello.s 编译, -nostdlib 让 gcc 不链接标准库。或者,把 _start 改成 main。

 

debug 的常用命令:

1、R: 寄存器显示与更改(Register)
格式:R [寄存器]
寄存器:AX BX CX DX SP BP SI DI DS ES CS IP PC F

若R不带参数,则显示所有寄存器的内容和状态标志、下一指令。
若指定新值,在显示内容后,给出冒句提示输入新值。回车结束。
对状态字F,在连字符 - 后以空格间隔输入新值,次序不计。
若直接回车,则跳过修改,寄存器内容不变。 

2、D: 显示内存内容(Dump)
格式:D [段地址:起始偏移地址] [结尾偏移地址]
内存内容显示指令,以十六进制和ASCII码形式显示指定范围内的内存内容。
若不指定范围,第一次按目标程序的 CS:IP 的位址开始显示显示 128byte 的内容,以后使用上次显示的未地址的下一地址为开始进行显示。

3、E: 数据的输入(Entering)
格式:E [段地址:起始偏移地址] 数值列表(可以是数字、字符、字符串、机器码,以空格隔开)
向内存区域输入数据。数据以十六进制形式,或以ASCII码形式均可,覆盖掉原有数据。
十六进制时要用空格、逗号或制表符加以分隔。字符串则要用单引号或双引号括起且区分大小写。
若不指写段址,则默认为 DS 值,每写完一数据地址自动增加。
如省略数值列表,可以提问的方式逐个修改从某一地址开始的内存单元中的内容,点号前为该字节原始值,点号后请求输入。这时若按空格,跳过这一字节,输入下一字节;按回车,结束输入;按减号或连字符,显示或修改前一字节内容。 字符串只能以数值列表的形式输入,不能按提问的方式输入。 

4、U: 反汇编(Unassemble)
格式:U [段地址:起始偏移地址] [结尾偏移地址]
将机器指定解码为汇编语言的助记符,若地址范围中无段址时,默认使用CS值。若不含末地址或长度,则自给定始地址起反汇编32个字节。以后由前次U最后一指令的下一指令做32字节的反汇编。
若从没用过U,则于CS:IP开始进行反汇编。
只能对8086指令解码,对其它以DB来显示。 

5、T: 程序执行跟踪(Trace)
格式:T [=段地址:起始偏移地址] [指令数]
没有 [指令数] 时,默认执行单条指令,显示寄存器及下一条指令。
没有 [=段地址:起始偏移地址] 时,则默认为 CS:IP 寄存器的值。

6、A: 编写汇编代码(Assemble)
格式:A [段地址:起始偏移地址]
用途:程序允许在指定位置(若无缺省为IP指针位置)进行汇编程序书写,相比于 E 命令写入机器指令要方便很多,使用方法也类似于 E 命令的提问方式。
对内存地址加[]以与立即数区分。 

 

栈:push pop

任意时刻,SS:SP 指向栈顶元素。

push ax ——> SP=SP-2 && mov SS:SP ax

pop ax ——> mov ax SS:SP && SP=SP+2

 

jmp short 标号

jmp near ptr 标号

jmp far ptr 标号:标号为四字节,前两个字节是IP(高位地址放高位,低位地址放低位),后两个字节是CS(高位地址放高位,低位地址放低位),不同于上面的,这里给出的是目标的 CS:IP 的绝对地址

(CS)=标号所在段的段地址

(IP)=标号所在段的偏移地址

 

jmp word ptr 内存单元地址(段内转移):跳转到 [内存单元地址] 中的值指定的地址,此处 [内存单元地址] 存放一个字。 

jmp dword ptr 内存单元地址(段间转移):此处 [内存单元地址] 存放两个字,(CS)=(内存单元地址+2),(IP)=(内存单元地址)

 

jcxz 标号:条件转移指令,都是短转移,对应的机器码中包含转移的位移,而不是目的地址。如果 cx 为 0,则转移到标号处执行,否则不跳转。当 (cx)=0 时,(IP)=(IP)+8 位位移。相当于 if( (cx)==0) jmp short 标号;

loop 标号:(cx)--; if ( (cx) !=0) jmp short 标号

 

call 和 jmp 的区别,只是多做了一步把当前地址入栈的操作。

 

mul 与 div

8位相乘:AX中

16位相乘:高位放于DX中,你们放于AX中

 

 

 

 

DOS下,一般合法程序都不会使用 0:200 ~ 0:2ff (00200h~002ffh)的 256 个字节空间,所以我们可以拿来学习。

 

8个通用寄存器:

AX (Accumulator)  累加寄存器,可分为 AH 和 AL,属于数据

BX (Base)  基址寄存器,可分为 BH 和 BL

CX (Counter)  计数寄存器,可分为 CH 和 CL

DX (Data)  数据寄存器,可分为 DH 和 DL

SP (Stack Pointer)  堆栈指针寄存器,用来指示栈顶的偏移地址

BP (Base Pointer)  基址指针寄存器,与段寄存器 SS 联用,可作为堆栈区的一个基地址,以相对方式访问堆栈中的存储单元。

SI (Source Index)  源变址寄存器,与段寄存器 DS 联用,用来确定数据段中某一存储单元的地址。

DI (Destination Index)  目的变址寄存器,可与 DS、ES 联用,用来确定数据段或附加段中某一存储单元的地址。

 

四个段寄存器:

CS (Code Segment) 存放程序段首地址

DS (Data Segment) 存放数据段首地址

ES (Extra Segment) 存放数据段首地址

SS (Stack Segment) 存放堆栈段首地址

 

两个控制寄存器:

IP

FR

 

 

 

posted @ 2013-10-09 12:33  轻典  阅读(995)  评论(0编辑  收藏  举报