8086汇编语言

8086汇编语言

经过我这几年的工作,发现不学点底层的知识感觉心里很慌……

语法格式&关键字说明

1.mov ds:[0h],ax  如果你不写段地址,段地址的默认地址就是数据地址;mov [0h],ax 如果你想访问数据段里的某一个内容,你可以这样写;默认前面就是ds:

2.寄存器是寄存器,内存是内存;寄存器访问本来就快,它是在CPU内部

3.把数据放放到数据段,与放到全局变量是一样的;把返回值放到ax寄存器中;ax是16位能用寄存器;eax是32位的寄存器;rax是64位的寄存器;

4.word ptr  中的ptr指的是pointer;可以用寄存器,全局变量来传参;

5.ios 里面的传参是把参数放先放到寄存器中,寄存器不够用了,再放到栈里面,因为寄存器快

6.16位的cpu 栈一定会操作两个字节的;

7.bp是辅助栈使用的;不能直接使用sp+2  ,可以使用bp+2

8.在以前的认知中局部变量与参数 在函数调用完毕之后会自动消毁、销毁就是变成垃圾内存了;C语言里面的销毁是占用的内存变成垃圾内存了,不管那个内存了,以后别人要用的话可以拿去去用;这就相当于内存被释放了;不是内存被迫害坏;

9.函数调用前与函数调用后栈应该是一样的;add esp ,8 做了栈平衡

10.; 打印字符串    
    print:    

    ; ds:dx告知字符串地址    
    mov dx, offset string
    mov ah, 9h
    int 21h
    ret 

函数的局部变量:

1.局部变量不是你要多少个就分配多少个内存,而是一次性分配一定的空间,分配多少个由我们来定,局部变量是在栈区不在数据区,数据区一般是存放全部变量、静态变量、常量;

2.先把sp的值赋值给bp mov bp,sp 然后再减10 , sub sp,10;如果sp不减10可能会被覆盖,只要sp指针一站在sp-10处,sp-10前面的空间别人就碰不了了,我们一调用call ,就会调用push操作把下一条要执行的执令入栈;如果局部变量往栈里面放数据直接用内存指令就好了;bp+8是参数 bp-8是局部变量;局部变量是夹在bp与sp之间

3.ax就是拿来给你赋值的,与函数返回值的,不用会保护,你保护是没有用的,ax是给别人用的;保护就要保护ax以外你要用的寄存器

4.寄存器是哪个函数都能用的,所以要保护一下si、di、dx、cx,保护你用到的寄存器

5.汇编里面是不允许内存对内存,一定要通过寄存器

函数的调用流程一:

; 1.push 参数
; 2.push 函数的返回地址
; 3.push bp (保留bp之前的值,方便以后恢复)
; 4.mov bp, sp (保留sp之前的值,方便以后恢复)
; 5.sub sp,空间大小 (分配空间给局部变量)
; 6.保护可能要用到的寄存器
; 7.使用CC(int 3)填充局部变量的空间  

; 8.--------执行业务逻辑--------      

; 9.恢复寄存器之前的值
; 10.mov sp, bp (恢复sp之前的值)
; 11.pop bp (恢复bp之前的值)
; 12.ret (将函数的返回地址出栈,执行下一条指令)
; 13.恢复栈平衡 (add sp,参数所占的空间)

下面是函数调用代码

assume ss:stack ds:data cs:code 

stack segment  
    db 60 dup(0)
stack ends  

data segment 
    db 20 dup(0)
data ends  

code segment 
 start:  
    mov ax,stack
    mov ss,ax
    mov ax,data
    mov ds,ax 
    
    push 1122h ;can shu
    push 3344h ;can shu
    call sum

    mov ax,4c00h
    int 21h   ;int 是interrupt 的缩写
     
    sum: 
        push bp
        mov bp,sp
        sub sp,10  
        
        push si
        push di
        push dx

        mov ax,0cccch
        mov bx,ss 
        mov es,bx
        mov di,bp
        sub di,10
        mov cx,5
        rep stosw 


        ;=======函数内部的业务逻辑    begin =====
        mov  word ptr ss:[bp-2],5566h     ;局部变量
        mov  word ptr ss:[bp-4],6677h   ;局部变量  
        mov ax,ss:[bp-2]
        add ax,ss:[bp-4]
        mov ss:[bp-6],ax
        
        mov ax,ss:[bp+4]
        add ax,ss:[bp+6]  
        add ax,ss:[bp-6]   
         ;=======end =====

         pop dx

         pop di
         pop si

 
        push 2
        push 1
        call minus
        
        mov sp, bp
        pop bp
        
     ret 4  ;内平栈  
     
     minus: 
         push bp
         mov bp,sp
         sub sp,10 
         
         push si
         push di
         push dx

        mov ax,0cccch
        mov bx,ss 
        mov es,bx
        mov di,bp
        sub di,10
        mov cx,5
        rep stosw 

         
         mov  word ptr ss:[bp-2],3   
         mov  word ptr ss:[bp-4],4
         
         mov ax,ss:[bp+6] 
         sub ax,ss:[bp+4]
         mov ax,ss:[bp-4]
         sub ax,ss:[bp-2]

         pop dx

         pop di
         pop si
    
         mov sp,bp
         pop bp
     ret 4  ;内平栈  
  
code ends  
end start

局部变量的填充:

1.windows平台的局部变量填充用的是cc,为什么要填充那?防止程序异常的时候,比如说用户做了违法的操作(这个应用不允许的一些操作)cs:ip; 如果牵扯到内存copy的时候就用到es:di了,左边的内存拷贝到右边的内存一般会用到es:di ;32位它所有段都是一样的,es,ss,ds都是一样的大家公用一个段不像8086两个16位合成一个20位段地址:偏移地址

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值