小生--汇编语言笔记7-8章,共10章
小生--汇编语言笔记1-6章:https://www.52hb.com/thread-1094-1-1.html小生--汇编语言笔记7-8章:https://www.52hb.com/thread-1095-1-1.html
小生--汇编语言笔记9-10章:https://www.52hb.com/thread-1096-1-1.html
如果对你有帮助,请评分吧,评分是不用花的钱的喔。不看不注意,原来这么长,我已把10章的内容整理到WORD文档里了,供大家下载看,如果有兴趣看网页的,就向下看吧,没有兴趣看的就直接下下来慢慢看吧!
WORD文档下载请移步:https://www.52hb.com/thread-1094-1-1.html
呵呵!2011马上就要过去了,终于赶在年前把10章之前的笔记写完了,为确保不使新手误入迷途,这几章笔记吸取了1—6章笔记的不足,更易懂,简洁,所有例子均为课本外的程序,所有代码都是经过调试,确保无误!
7——10章也是本书的重点和难点,难就难在一个思路和思维行,难在灵活性,说是重点,跳转命令,灵活内存地址定位,都是以后逆向或者编写复杂程序的基础!这么说,学汇编就像红军过草地,很多有志之士,热血沸腾的!但都是倒在了7—10章这里没走过去,能迈过这几章的,前面都是一片光明!
第七章:
学过C语言的都知道,在C语言中,也有逻辑与运算和逻辑或运算。汇编语言当然也有
and 和or就是
我是这么理解and和or
and的是逻辑与运算,相当于两人谈感情,0代表假,1代表真,那么必须两人同时为
真也就是1的时间,结果才能为真,如果一个人为假就是零,那么结果也就是0
如:
mov al,11111111b
and al,00000000b
那么结果就是:00000000
or是逻辑或运算,就是一厢情愿,只要有一方愿意付出,愿意为真,那么结果就能为真
如:
mov al,11111111b
oral,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中查看寄存器变化和相应地址空间的值。
待续...
我们之前学过这个用法,他得段寄存器是ds,是他得偏移地址
例如:
mov cx,
意思就是:把段地址为ds,偏移地址为bx+100的这个内存单元的数据送人cx中
逻辑表达就是ds*16++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,
and al,11011111b
mov ,al
mov al,
or al,00100000b
mov ,al
inc bx
loop s
mov ax,4c00h
int 21h
qq ends
end start
si和di这两个寄存器,和bx寄存器功能相近,作为偏移地址时,他们的段地址都默认在ds中存放
如:mov bx,1
mov al,
mov si,1
mov al,
功能一样!
唯一不同的是,bx可以分为bl和bh两个8位寄存器,而si和di不能分成两个8位寄存器
书上7.2,把wlcome to masm 复制到他后面的数据区中,
我们先用的方法来写,一次复制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,
mov ,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,
mov ,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,
mov ,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,
mov ,al
inc di
inc si
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
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,
and al,11011111b
mov ,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,
and al,11011111b
mov ,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,
and al,11011111b
mov ,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,
就等于:
ax=ss*16+(bp)
关于,bx,bp,si,di四个寄存器的配合
很多人晕,我是这样记的:
假设:
bx和bp是两个男人,像我一样帅!呵呵,bx是我本人,bp就是你
了,他们名字的姓分别是bx姓ds bp姓ss
si和di是两个女孩 很漂亮是亲姐妹,比如si是丁丁(人名),di是斜阳(人名),等
下封ID了...
idata呢,就是小三了,像谁呢?你猜
一共5个人哈!记好!
根据我多年对易术天圆地方的研究!以及我多年的物理学经验,终
于得出一个结论:正负相吸,相同排斥的原理!
男女搭配的常规的四种搭配方式:
分别是:我和丁丁,我和斜阳
分别是:你和丁丁,你和斜阳
当然,如果想搞小三的话,那可以加上idata,甲鱼(人名)常常
多少个idata,谁知道呢???
如:
那这样就是,我和丁丁,外加小三....这种三人关
系还是可以的,我喜欢....
你有钱的话,还可以多找几个小三,像甲鱼一样:
注意:绝不允许两个男人娶一个老婆,如:
如,我和甲鱼和丁丁,这样甲鱼是肯定不会愿意的
,所以甲鱼只好走了,就剩我和丁丁,如: 当然这个时间
我还可以找个小三 ,如
但是不能找斜阳了,不然就乱伦了...那就是 这样绝对不
行
还有就是连同小三我们五个人都单身一辈子,都单身一辈可以5个
单独出现,所以说:
亲!你是不是经常男女搭配啊!
亲!你是不是经常乱伦啊!
亲!你是不是经常同性恋啊!
亲!你是不是经常包小三啊!
亲!你是不是经常单身啊!
有木有???
还有就是si和di不能一起,因为乱伦了!
注意:si可以单独和idata在一起,哎!这个关系怎么可以?设计
CPU的人啊!伤不起...
最后讨论下生出孩子的问题,主要是孩子姓什么?
注意一点:
很多人认为,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,或mov ax,
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 ,33h
mov ax,4c00h
int 21h
qq ends
endstart
这样的话,结果是
ds:0 33 00 00 00
我们虽然修改了11,但同时也把22给修改了
因为此时没有出现寄存器,所以cpu就认为是字运算了
,如果我们要单独修改11的话,那就用一条新指定
XX ptr
解析:xx可以是word或者byte...
如字运算: mov word ptr,33h
如字节运算:mov byte ptr,33h
这样的话,我们改进上面的程序,把mov ,33h
这一句修改为:mov byte ptr,33h
程序结果如下:
ds:033 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,'0'
mov byte ptr,'1'
mov byte ptr,'0'
mov byte ptr,'d'
mov byte ptr,'o'
mov byte ptr,'c'只修改一个字节
mov word ptr,'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
商al=(ax)/(ds*16+bx)
余ah=(ax)/(ds*16+bx)
如果除数为16位时,被除数为32位,默认放在ax和dx中,
其中bx存放高16位,ax存放低16位
商则放在ax中,余数则放在dx中
例:
div word ptr
商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
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:
movword ptr ax,
movword ptr ,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 ,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,
mov word ptr ,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 ,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:
movax,
mov ,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 ,0
add bp,16
loop s8
;最后的空格
mov bp,0
mov cx,6
s9:
mov byte ptr ,0
add bp,16
loop s9
;除法运算,商保存偏移OD处,余保存0E处
mov bp,0
mov cx,6
mov si,0
ps:
mov bx,0
mov ax,
mov dx,
div word ptr
mov ,ax
mov ,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,
mov es:,ax
mov ax,.2
mov es:.2,ax
mov ax,.84
mov es:.5,ax
mov dx,.86
mov es:.7,dx
div word ptr ds:.168
mov es:.13,ax
mov ax,.168
mov es:.10,ax
add di,2
add bx,4
add si,16
loop s
mov ax,4c00h
int 21h
code ends
end start
OK 第八章算是结束了,下面就是第九种跳转了
呵呵!逆向的必备!
未完...
多谢大佬分享。 收藏起来,,,谢谢 学习学习,,, 谢谢大佬的分享 正需要,过来学习内容! 感谢分享
页:
[1]
2