|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 小生我怕怕 于 2012-4-24 03:27 编辑
呵呵!2011马上就要过去了,终于赶在年前把10章之前的笔记写完了,为确保不使新手误入迷途,这几章笔记吸取了1—6章笔记的不足,更易懂,简洁,所有例子均为课本外的程序,所有代 码都是经过调试,确保无误!
7——10章也是本书的重点和难点,难就难在一个思路和思维行,难在灵活性,说是重点,跳转命令,灵活内存地址定位,都是以后逆向或者编写复杂程序的基础!这么说,学汇编就像红军过草地,很多有志之士,热血沸腾的!但都是倒在了7—10章这里没走过去,能迈过这几章的,前面都是一片光明!
鱼C官方汇编讨论一群:158781547 欢迎汇编爱好者加入!
注意:由于笔记字数过多,帖子限制20000字,所以:一楼回沙发也是!由于制作水平有限,时间仓促,如有错误之处,欢迎回帖纠正!
第七章:
学过C语言的都知道,在C语言中,也有逻辑与运算和逻辑或运算。汇编语言当然也有
and 和or就是
我是这么理解and和or
and的是逻辑与运算,相当于两人谈感情,0代表假,1代表真,那么必须两人同时为
真也就是1的时间,结果才能为真,如果一个人为假就是零,那么结果也就是0
如:
mov al,11111111b
and al,00000000b
那么结果就是:00000000
or是逻辑或运算,就是一厢情愿,只要有一方愿意付出,愿意为真,那么结果就能为真
如:
mov al,11111111b
or al,00000000b
那么结果就是:11111111b
ASCII码:
呵呵,这个和摩斯电码很像,喜欢无线电技术的朋友会有所体感,一个指定的值代表一个英文字母,就想电视中,嘀嘀 嘀 滴滴 滴滴 呵呵!这个是无线电台相互交流时所采用的一种编码,电脑也有,我们常用的如ASCLL码,当然还有其他很多。
ASCII表。百度一下,有很大这种表,不需要大家死记,但最好能记得其中的规律。
当你打开一个win下得文本编辑器时,按下键盘的A键,屏幕上就会显示出A,具体是
怎么实现的呢?如下:
1.电脑开机,打开编辑器,按下键盘的A
2.按下以后,键盘会把这个信息传送给计算机,计算机内部通过ASCLL码进行编码,将对应值61H存储在内存空间中,
3.编辑器,从相应的内存空间取出这个值61H,送入显卡的显存当中,此事工作在文本模式下得显卡,就会利用ASCLL码进行解码,就会把61H转换为字符A
4.此时显卡驱动显示器,将A的图像显示在屏幕上,我们也就能看到
结论:大写A在ASCLL码中对应的是61H,注意这是十六进制的61.
关于其他ASCLL码值,请大家自行下载ASCLL表进行查看
以字符形式给出数据
形式为:‘...’单引号,注意是英文的单引号
如:db‘ABCD’
还不懂存储单元转换的,看日志揭秘系列的单讲。
打下这个程序:
assume cs:qq,ds:ww (把qq,ww分别和寄存器CS,DS扯上关系)
ww segment (ww段开始)
db'abcd' (定义数据,把abcd对应的ASCLL码放入地址空间)
db'ABCD' (同上)
ww ends (ww段结束)
qq segment (qq段开始)
start: mov al,'a' (start定义程序入口,mov...意思把a的ASCLL值值放入寄存器al中)
mov bl,'b' (同上)
mov ax,4c00h(和一面一句,以后解释)
int 21h
qq ends (qq段结束)
end start (程序结束,这个start和前面的staet对应)
大家可以载入debug中查看寄存器变化和相应地址空间的值。
待续...
[bx+idata]
我们之前学过[bx]这个用法,他得段寄存器是ds,[bx]是他得偏移地址
例如:
mov cx,[bx+100]
意思就是:把段地址为ds,偏移地址为bx+100的这个内存单元的数据送人cx中
逻辑表达就是ds*16+[bx]+100
运用这种方法,处理大小写转换的问题:
程序如下:
assume cs:qq,ds:ee
ee segment
db 'FisHc'
db 'LiNuX'
ee ends
qq segment
start:mov ax,ee
mov ds,ax
mov bx,0
mov cx,5
s:mov al,[bx]
and al,11011111b
mov [bx],al
mov al,[bx+5]
or al,00100000b
mov [bx+5],al
inc bx
loop s
mov ax,4c00h
int 21h
qq ends
end start
si和di这两个寄存器,和bx寄存器功能相近,作为偏移地址时,他们的段地址都默认在ds中存放
如:mov bx,1
mov al,[bx+100]
mov si,1
mov al,[si+100]
功能一样!
唯一不同的是,bx可以分为bl和bh两个8位寄存器,而si和di不能分成两个8位寄存器
书上7.2,把wlcome to masm 复制到他后面的数据区中,
我们先用[bx+idata]的方法来写,一次复制1字节
assume cs:qq,ds:ee
ee segment
db 'welcome to masm!'
db '...............'
ee ends
qq segment
start:mov ax,ee
mov ds,ax
mov bx,0
mov cx,16
s:mov al,[bx]
mov [bx+16],al
inc bx
loop s
mov ax,4c00h
int 21h
qq ends
end start
一次复制2字节:
assume cs:qq,ds:ee
ee segment
db 'welcome to masm!'
db '...............'
ee ends
qq segment
start:mov ax,ee
mov ds,ax
mov bx,0
mov cx,8
s:mov ax,[bx]
mov [bx+16],ax
add bx,2
loop s
mov ax,4c00h
int 21h
qq ends
end start
用si和di一次复制两个字:
assume cs:qq,ds:ee
ee segment
db 'welcome to masm!'
db '...............'
ee ends
qq segment
start:mov ax,ee
mov ds,ax
mov cx,8
mov di,0
mov si,16
s:mov ax,[di]
mov [si],ax
add di,2
add si,2
loop s
mov ax,4c00h
int 21h
qq ends
end start
用si和di一次性复制一个字节:
assume cs:qq,ds:ee
ee segment
db 'welcome to masm!'
db '...............'
ee ends
qq segment
start:mov ax,ee
mov ds,ax
mov cx,16
mov di,0
mov si,16
s:mov al,[di]
mov [si],al
inc di
inc si
loop s
mov ax,4c00h
int 21h
qq ends
end start
其实第七章注重一个灵活
如:
[bx]
[idata]
[bx+idata]
[bx+si]
[si+bx+idata]
把
db '1.fishc..'
db '2.linux..'
db '3.unix...'
db '4.windows'
首字母设置为大写:
代码如下:
assume cs:qq,ds:ee
ee segment
db '1.fishc..'
db '2.linux..'
db '3.unix...'
db '4.windows'
ee ends
qq segment
start:mov ax,ee
mov ds,ax
mov bx,0
mov cx,4
s:mov al,[bx+2]
and al,11011111b
mov [bx+2],al
add bx,9
loop s
mov ax,4c00h
int 21h
qq ends
end start
把
db '1.fishc..'
db '2.linux..'
db '3.unix...'
db '4.windows'
所有字母设置为大写:
代码如下:
assume cs:qq,ds:ee,ss:tt
ee segment
db 'dll'
db 'exe'
db 'dos'
db 'win'
ee ends
tt segment
db '......'
tt ends
qq segment
start:mov ax,ee
mov ds,ax
mov ax,tt
mov ss,ax
mov sp,12
mov bx,0
mov cx,4
s1:
push cx
mov si,0
mov cx,3
s:mov al,[bx+si]
and al,11011111b
mov [bx+si],al
inc si
loop s
add bx,4
pop cx
loop s1
mov ax,4c00h
int 21h
qq ends
end start
双层循环,多想想就明白了
最后一例:
把
db '1.fishc..'
db '2.linux..'
db '3.hacker...'
db '4.windows'
把前四个字母设置为大写:
代码如下:
assume cs:qq,ds:ee,ss:tt
ee segment
db '1.linux..'
db '2.hacker.'
db '3.windows'
ee ends
tt segment
db '..........'
tt ends
qq segment
start:
mov ax,tt
mov ss,ax
mov sp,20
mov ax,ee
mov ds,ax
mov bx,0
mov cx,3
s:
push cx
mov si,0
mov cx,4
s1:mov al,[bx+si+2]
and al,11011111b
mov [bx+si+2],al
inc si
loop s1
add bx,9
pop cx
loop s
mov ax,4c00h
int 21h
qq ends
end start
(第七章完)第八章开始
首先是寄存器了,这里我们统计下之前所学的寄存器
首先四个:ax,bx,cx,dx,
si,di,sp,ip,(bp),(pws)
cs,ds,ss,(es)
其中:ax,bx,cx,dx,这四个可分为高低8位寄存器
如ah,al....
其中cx 用来计算循环次数
bx一般当做偏移地址来说时,段地址在ds中
其中cs,ds,ss,es这四个为段寄存器
cs和ip为组合, 定义指令指针
ss和sp为组合, 定义栈
ds和bx,si,di组合,定义数据
关于es以后再说
bp下面说
pws以后再说
其中si,di与bx功能相似,作为偏移地址时,段地址都在ds中
不一样的是不能向bx一样可以划分为单独的两个8位寄存器
十四个寄存器中,唯一没有接触过的是:es段寄存器,pws寄存器
bp寄存器
说了这么说,就介绍下bp寄存器
bp寄存器,实际上和sp很相似,默认段地址都在ss中,BP可以间
接寻址寄存器而SP不能以外,其余的功能基本相同
如:
mov ax,[bp]
就等于:
ax=ss*16+(bp)
关于,bx,bp,si,di四个寄存器的配合
很多人晕,我是这样记的:
假设:
bx和bp是两个男人,像我一样帅!呵呵,bx是我本人,bp就是你
了,他们名字的姓分别是bx姓ds bp姓ss
si和di是两个女孩 很漂亮是亲姐妹,比如si是丁丁(人名),di是斜阳(人名),等
下封ID了...
idata呢,就是小三了,像谁呢?你猜
一共5个人哈!记好!
根据我多年对易术天圆地方的研究!以及我多年的物理学经验,终
于得出一个结论:正负相吸,相同排斥的原理!
男女搭配的常规的四种搭配方式:
[bx+si] [bx+di] 分别是:我和丁丁,我和斜阳
[bp+si] [bp+di] 分别是:你和丁丁,你和斜阳
当然,如果想搞小三的话,那可以加上idata,甲鱼(人名)常常
[bp+si+idata...]
多少个idata,谁知道呢???
如:
[bx+si+idata] 那这样就是,我和丁丁,外加小三.... 这种三人关
系还是可以的,我喜欢....
你有钱的话,还可以多找几个小三,像甲鱼一样:
[bx+si+idata+idata+...]
注意:绝不允许两个男人娶一个老婆,如:
[bx+bp+si] 如,我和甲鱼和丁丁, 这样甲鱼是肯定不会愿意的
,所以甲鱼只好走了,就剩我和丁丁,如:[bx+di] 当然这个时间
我还可以找个小三 ,如[bx+si+idata]
但是不能找斜阳了,不然就乱伦了...那就是[bx+si+di] 这样绝对不
行
还有就是连同小三我们五个人都单身一辈子,都单身一辈可以5个
单独出现,所以说:
亲!你是不是经常男女搭配啊!
亲!你是不是经常乱伦啊!
亲!你是不是经常同性恋啊!
亲!你是不是经常包小三啊!
亲!你是不是经常单身啊!
有木有???
还有就是si和di不能一起,因为乱伦了!
注意:si可以单独和idata在一起,哎!这个关系怎么可以?设计
CPU的人啊!伤不起...
最后讨论下生出孩子的问题,主要是孩子姓什么?
注意一点:
[bp+idata]
[bp+di+idata]
[bp+si]
很多人认为,bp段地址在ss,di或者si段地址在ds
这样是错误的!
只要bp出现,那就是统一段地址在ss中
这样理解:
bp和bx说了是男人,si和di是女人,
夫唱妇随,孩子出生肯定跟随bp的姓了,那就是段地址在ss
idata是小三!
呵呵,肯定也是男的是bp就跟ss,是dx就跟ds
如果小三和si与di在一起了,那就跟si和di的姓,也是ds
说下数据处理和数据有关的方面
首先cpu处理数据,一般不关心数据值是多少,而是关心数据所在
位置,一般有三种操作,读,写,运行
一般数据在三个位置:
内存地址 如:mov ax,[bx]或mov ax,[bx+2]
cpu内部,如寄存器中,指令缓冲器... mov ax,bx或者mov ax,1
端口 暂时不说
数据进行运算时,一般不需要指定数据运算的单位,如字还是字节
那是因为很多运算使用了寄存器
如:mov ax,bx 默认就是字运算 如mov ax,1122h
注意:mov ax,12h 也是字运算,不要看只有12h就以为是字节运算
其实编译器当0012h
mov al,bl 默认是字节运算 如 mov al,22h
push和pop默认是字运算
如果在没有指定寄存器的情况下,不指定运算单位,就是要出错的
程序如下:
假设数据:
ds:0 11 22 00 00....
我们修改11为33,就是 33 22 00 00...
原来程序如下:
assume cs:qq,ds:ee
ee segment
db 11h,22h
ee ends
qq segment
start:
mov ax,ee
mov ds,ax
mov bx,0
mov [bx],33h
mov ax,4c00h
int 21h
qq ends
end start
这样的话,结果是
ds:0 33 00 00 00
我们虽然修改了11,但同时也把22给修改了
因为此时没有出现寄存器,所以cpu就认为是字运算了
,如果我们要单独修改11的话,那就用一条新指定
XX ptr
解析:xx可以是word或者byte...
如字运算: mov word ptr[bx],33h
如字节运算:mov byte ptr[bx],33h
这样的话,我们改进上面的程序,把mov [bx],33h
这一句修改为:mov byte ptr[bx],33h
程序结果如下:
ds:0 33 22 00 00
这样就做到没有修改到22这个数据!
关于寻址方式加定义处理数据单位的综合因为:
我就写了个最简单的例子,没有用到循环和别的,就是让大家
更明了
assume cs:qq,ds:ee
ee segment
db'IBM'
db'100'
db'PDF'
db'in'
ee ends
qq segment
start:
mov ax,ee
mov ds,ax
mov bx,0
mov byte ptr[bx+03h],'0'
mov byte ptr[bx+04h],'1'
mov byte ptr[bx+05h],'0'
mov byte ptr[bx+06h],'d'
mov byte ptr[bx+07h],'o'
mov byte ptr[bx+08h],'c' 只修改一个字节
mov word ptr[bx+09h],'hh' 同时修改1个字
mov ax,4c00h
int 21h
qq ends
end start
好了,第八章上半部分就说的这里!
第八章:
DIV命令
除法命令
说下我们之前学过的运算
add 加sub减inc自加1div除
了解基本除法运算
9/2=4...1
9是被除数
2是除数
4是商
1是余数
在8086汇编中,除数可能有8位与16位两种
除数为8位时,被除数为16位,默认放在ax寄存器中
商则放在al中,余数放在ah中
例:
div byte ptr [bx]
商al=(ax)/(ds*16+bx)
余ah=(ax)/(ds*16+bx)
如果除数为16位时,被除数为32位,默认放在ax和dx中,
其中bx存放高16位,ax存放低16位
商则放在ax中,余数则放在dx中
例:
div word ptr [bx+si+6]
商ax=(dx*10000H+ax)/(ds*16+bx+si+6)
余dx=(dx*10000H+ax)/(ds*16+bx+si+6)
这里的10000H解析下:
如果32位数据为:
AABBCCDD
那么AABB放在bx寄存器中
CCDD放在ax寄存器中
那么AABB*10000H时,也就是等于AABB0000
这个时间加上ax的值,那就是AABBCCDD
注意,一定要拿word ptr或者byte ptr指明是字节
还是字操作,也就是8位还是16位
举个例子
1000/101=9...101
程序如下:
assume cs:qq,ds:ee
ee segment
db 65h ;65h即等于十进制101
ee ends
qq segment
start:
mov ax,ee
mov ds,ax
mov ax,3E8h ;3E8h即等于十进制1000
mov bx,0
div byte ptr [bx]
mov ax,4c00h
int 21h
qq ends
end start
结果:ax=5B09
其中al=09即是商 ,十进制也是9
ah=5B即是余数 5Bh即十进制101
伪指令dd
其实前面我们说过了,
db定义字节 8位
dw定义字 16位
dd定义双字 32位
dup这个命令很有用,大家在使用一段干净内存空间时
可以用它来定义
dup功能:
XX y dup(a,b,c)
其中XX可以是dd,dw,db...
y即是重复的次数
括号内部的a,b,c即是要重复的内容
如
db 3 dup(11,22)
执行后,相当于
db 11,22,11,22,11,22
关于实验7,我用了一个笨方法下了出来,虽然笨,但是几乎用到
了前面的所有的知识
我把代码写下来
assume cs:qq,ds:ee
ee segment
db '1991','1992','1993','1994','1995','1996'
dd 16,22,382,1356,8000,5937000
dw 3,7,9,13,38,30000,17800
ee ends
;qq段开始
qq segment
start:
mov ax,ee
mov ds,ax
mov ax,1000h
mov ss,ax
;年份计算
mov bp,0
mov bx,0
mov si,0
mov cx,6
s:
mov es,cx
mov cx,4
s1:
mov word ptr ax,[bx]
mov word ptr [bp+si],ax
inc bx
inc bp
loop s1
mov cx,es
add si,12
loop s
;中间空格
mov bp,0
mov cx,6
s2:
mov byte ptr [bp+4],0
add bp,16
loop s2
;收入计算
mov cx,6
mov bx,18h
mov si,0
mov bp,0
s3:
mov es,cx
mov cx,2
s4:
mov word ptr ax,[bx]
mov word ptr [bp+si+5],ax
add bx,2
add bp,2
loop s4
mov cx,es
add si,12
loop s3
;中间空格
mov bp,0
mov cx,6
s5:
mov byte ptr [bp+9],0
add bp,16
loop s5
;雇员数计算
mov cx,6
mov bx,30h
mov si,0
mov bp,0
s6:
mov es,cx
mov cx,1
s7:
mov ax,[bx]
mov [bp+si+10],ax
add bx,2
inc bp
loop s7
mov cx,es
add si,15
loop s6
;中间空格
mov bp,0
mov cx,6
s8:
mov byte ptr [bp+12],0
add bp,16
loop s8
;最后的空格
mov bp,0
mov cx,6
s9:
mov byte ptr [bp+15],0
add bp,16
loop s9
;除法运算,商保存偏移OD处,余保存0E处
mov bp,0
mov cx,6
mov si,0
ps:
mov bx,0
mov ax,[bp+si+5]
mov dx,[bp+si+7]
div word ptr [si+bp+10]
mov [bp+si+13],ax
mov [bp+si+14],dx
add si,16
loop ps
;结束
mov ax,4c00h
int 21h
qq ends
end start
书上原题,答案是这样的:
assume cs:code,ds:data,es:table
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11452,14430,15257,17800
data ends
table segment
db 21 dup ('year summ ne ?? ')
table ends
code segment
start: mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0
mov si,0
mov di,0
mov cx,21
s: mov ax,[bx]
mov es:[si],ax
mov ax,[bx].2
mov es:[si].2,ax
mov ax,[bx].84
mov es:[si].5,ax
mov dx,[bx].86
mov es:[si].7,dx
div word ptr ds:[di].168
mov es:[si].13,ax
mov ax,[di].168
mov es:[si].10,ax
add di,2
add bx,4
add si,16
loop s
mov ax,4c00h
int 21h
code ends
end start
OK 第八章算是结束了,下面就是第九种跳转了
呵呵!破解的必备!
未完...看一楼......
|
本帖被以下淘专辑推荐:
- · 学习汇编|主题: 2, 订阅: 4
- · 我的土墙|主题: 12, 订阅: 1
- · 收帖|主题: 2, 订阅: 0
|