首页
社区
课程
招聘
[分享]80X86汇编学习心得
发表于: 2017-1-22 01:09 5062

[分享]80X86汇编学习心得

2017-1-22 01:09
5062
    在整理之前学习的一些资料,这是暑假时候学习汇编语言的一些收获,和大家相互学习,本人也属于菜鸟初学者,看的是王爽的那本汇编语言,主要是前十一章的(因为想着是学习逆向,后边的就没看了)。

     先是一些汇编编程的细节:
-1 在编写汇编程序时要注意十六进制数不能以字母开头,如果原始数是以字母开头,要在前面加上0,否则在编译的时候就不能被识别出 来,如果不是以字母开头则不作改变,并以H/h结尾表示该数是十六进制数。

-2 在初始化阶段,在定义一个段的时候,可以同一个段里根据需要定义多个不同的段,段的名字根据需要也可以定义为易读的名字,在编译的时候段寄存器和段的名字是由编译器识别,并将二者联系在一起

-3 执行“jmp short 标号”等指令时,进行的是短转移,即段内转移,cup并不知道标号的地址,也就是说cpu并不清楚要跳到哪里,cpu根据的是指令在编译的时候由编译器计算得到的需要跳转的位移大小,(IP = IP + 8位位移,8位位移 = 标号的地址 - jmp指令后面第一个字节的地址,范围是-128~ 127),超过范围会报错。cup所知道的就是这个位移,它并不管目的地址在哪里,只需要知道位移即可,位移的计算交由编译器完成,所以说这时cpu并不需要知道转移的目的地址。

-4  内存地址中B8000h-B8fffh共32k的空间,为80x25彩色字符模式的显示缓冲区,向这个地址空间写入数据,写入的内容将立即显示在显示器上。

-5 PC机主板的ROM写有一个生产日期,在内存fff00h-fffffh的某几个单元中,这类值是修改不了的。

-6 在执行“call 标号”指令的过程,首先明白它实现的是段内转移,首先是push ip,这里的ip是指“call 标号”指令后面第一个字节处的地址,并不是该指令对应的机器码中e8后面两个字节的内容,执行完push ip后,ip = ip + 16位位移,执行这个动作根jmp指令原理相同,16位位移 = 标号处的地址 - “call 标号”指令后面第一个字节处的地址。可见,在这么些跳转指令中,这些指令后面第一个字节处的地址起着关键性作用。“call far ptr 标号”进行的是段间转移,过程跟前面差不多。都是用栈来保存当前的ip(cs)。

-7 当执行完一条指令后,ip = ip + 该指令所占字节长度,这个动作是无条件执行的。

-8 执行乘法指令mul的时候,如果是八位以内,结果存放在AX(255*255 = 65025<65535)中,如果是16位以内,以80x86cpu为例,结果的低16位存放在AX,高16位存放在DX中,空余位置自动补零。

-9 在flag寄存器中记录了每条指令执行后各个状态位的情况,要注意的是有些指令不影响这些状态位,比如loop指令,inc指令;另外cmp指令执行后看的是flag寄存器中的情况,并不影响参加运算的寄存器的数据。

 上面说的好像不痛不痒,就是在学习的时候遇到的觉得重要所以就记下了,下面是几个例子,可以帮助理解。

00:汇编中循环的原理
;在进行调试的时候,第一次用P只是进行了首轮循环,第二次再下P才会将剩下的所有循环进行完,所以这种情况只用一次P是不够的,P的使用得要结合具体情况
assume cs:codesg,ds:datasg,ss:stacksg
datasg segment
db 'ibm.............'
db 'dec.............'
db 'dos.............'
db 'vax.............'
        
datasg ends

stacksg segment
 dw 0,0,0,0,0,0,0,0;定义一个stack,用来保存cx
stacksg ends
 codesg  segment
star :
      mov ax,datasg
      mov ds,ax
    mov bx,0
    mov cx,4
    
  s:push cx ;将外层循环的cx保存在stack
    mov si,0
    mov cx,3 ;cx作为内层循环的次数
d:   mov al,[bx+si]
    and al,11011111b
    mov [bx+si],al
    inc si
    loop d 
    
    add bx,16
    pop cx ;将stack中的值还原给cx
    loop s 
mov ax,4c00h
int 21h
codesg ends
end star

01:初识汇编结构体
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 

02深入理解jmp指令(段内转移)
assume cs:codesg
codesg segment
    mov ax,4c00h
    int 21h
start : mov ax,0
s:      nop
      nop
     
      mov di,offset s
      mov si,offset s2
      mov ax,cs:[si]
      mov cs:[di],ax
s0:     jmp short s
s1:     mov ax,0
        int 21h
        mov ax,0
s2:     jmp short s1 
        nop 
codesg ends
end start       
     
code ends

03在显存中写入内容以彩色显示

assume cs:code

data segment

     db 'welcome to masm!'

data ends

code segment

start:   mov ax,data

     mov ds,ax

     mov ax,0b800h

     mov es,ax

     mov bx,0720h                ;关键点1 : 设置中间行中间列的首地址 160*11+64  

     mov si,0

     mov cx,16

s:   mov ax,[si]       ;关键点2 : si控制字符的变化

     mov ah,2h

     mov es:[bx],ax              ;设置绿色字体

     mov ah,24h

     mov es:[bx].0a0h,ax         ;关键点3 :设置绿底红色,0a0h相当于十进制的160,即跳到下一行的相同位置处

     mov ah,71h

     mov es:[bx].0a0h.0a0h,ax    ;设置白底蓝色,灵活的运用ah进行字符颜色属性的修改

     inc si                      ;指向下一字符

     add bx,2                    ;指向下一显存单元

     loop s

     mov ax,4c00h

     int 21h

code ends

end start

04大小写转换
assume cs:code

code segment

data segment
db 'word',0
db 'unix',0
db 'name',0
db 'byte',0
data ends 

start: mov ax,data 
     mov ds,ax 
     mov bx,0 
     mov cx,4 
     
   
s:     mov si,bx 
     push cx
       call fun 
     pop cx 
     add bx,5 
     loop s 
     
fun :  mov cl,ds:[si] 
       mov ch,0 
       and [si],11011
     ;有个细节要注意,[si]是byte数据,所以11011111应该也是八位,空位根据情况补齐,不然8位与7位无法运算
       jcxz s1
     inc si 
       jmp short fun
   s1: ret      
       
code ends
end start

  最后是几个反汇编中常遇到的条件转移指令:
 --------------------------------------------------------------------------------
指令                  含义                              相关标志位的状态
 --------------------------------------------------------------------------------
je                   等于则跳转                         ZF = 1

jen                 不等于则跳转                      ZF = 0   

jb                   低于则跳转                         CF = 1

jnb                 不低于则跳转                      CF = 0  

ja                   高于则跳转                         CF = 0 , ZF = 0  

jna                  不高于则跳转                     CF = 0 或 ZF = 0 
 --------------------------------------------------------------------------------
这些东西,前人之述备矣,虽然东西一样,想想还是放上来,因为经验不一样

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 768
活跃值: (530)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
2
怀念 16 位汇编的时光。。。
2017-1-22 10:14
0
雪    币: 49
活跃值: (118)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
16位确实好老了
2017-1-22 11:00
0
雪    币: 768
活跃值: (530)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
4
裸机接管MBR,然后画点阵界面,按钮,菜单,哇哈哈。。
时间好快啊,回忆。。。
2017-1-22 16:45
0
游客
登录 | 注册 方可回帖
返回
//