汇编学习之路(一)当bp大于sp的时候,bp所指向的值无法修改

本文介绍了divdw指令的基本用法,包括其参数、功能及应用举例。通过divdw指令,可以实现dword型数据除以word型数据,确保运算过程不会发生溢出。
;名称:divdw
;功能:进行不会产生溢出的除法运算,被除数为dword型,除数word型,结果为dword型。
;参数:(ax)=dword型数据的低16位
; (dx)=dword型数据的高16位
; (cx)=除数
;返回:(dx)=结果的高16位,(ax)=结果的低16位
;   (cx)=余数
;公式:X/N = int(H/N)*65536+[rem(H/N)*65536+L]/N
;应用举例:计算1000000/10(F4240H/0AH)
assume cs:code,ss:stack
stack segment
dw 16 dup(0) ;定义32个字节的数据
stack ends


code segment
start: mov ax,stack
mov ss,ax
mov sp,32

mov ax,4240H
mov dx,000FH
mov cx,0AH
call divdw

mov ax,4c00h
int 21h

divdw: push bp

mov bp,sp

sub sp,6;当bp>sp的时候,bp所指向的值无法修改,
;如果把这一行去掉,下面的类似于mov [bp-2],dx的命令全部无效

mov [bp-2],dx ;存储被除数的高16位
mov [bp-4],ax ;存储被除数的低16位
;计算int(H/N)*65536部分,此部分计算后低位ax为0
mov ax,[bp-2] ;先进行高位的运算
mov dx,0 ;除数为16位,则被除数为32位,高位补零
div cx ;做除法运算的余数dx,直接作为后续除法运算的高位


mov [bp-6],ax ;*65536也即*10000h,直接将商作为高16位即可


;计算[rem(H/N)*65536+L]/N部分,此部分计算后低位ax为最终结果
mov ax,[bp-4] ;做乘法运算高位存储在dx,低位ax为0,直接将被除数的低位复制到ax即可


div cx
;计算int(H/N)*65536+[rem(H/N)*65536+L]/N,将前面两部分的dx相加
add dx,[bp-6]

mov cx,0 ;根据书中的结果,cx最后赋值为零

pop bp
ret
code ends
end start





<think>我们正在讨论汇编语言中的BP寄存器(Base Pointer Register)。根据引用[1]中的信息,BP寄存器属于通用寄存器,具体是基址指针寄存器。在16位CPU架构中,BP寄存器通常用于访问堆栈段中的数据。 在8086汇编中,堆栈段由SS寄存器指向,而SP寄存器(堆栈指针)指向堆栈的顶部。BP寄存器则通常被用作指向堆栈帧中的基地址,以便访问函数参数和局部变量。当使用BP寄存器时,默认的段寄存器是SS(堆栈段)。 常见的用法是在子程序(函数)中,我们通常用BP来访问传递给函数的参数和局部变量。例如: 1. 进入子程序时,通常会保存旧的BP(压栈),然后将当前的SP赋给BP,这样BP指向了当前堆栈帧的基地址。 2. 然后通过调整SP来为局部变量分配空间。 3. 在子程序内部,可以通过[BP+位移]的方式来访问参数和局部变量。 例如: - 在调用子程序之前,调用者将参数压入堆栈。 - 进入子程序后: push bp ; 保存旧的BP mov bp, sp ; 将当前栈顶作为新的基址 sub sp, n ; 为局部变量分配n字节空间 此时,堆栈布局大致如下: [BP+4] 返回地址的高位(如果是在16位实模式下,返回地址是2个字,即4字节) [BP+2] 返回地址的低位 [BP] 旧的BP(现在被保存) 参数1:通常位于[BP+6](假设返回地址是2字节,旧BP是2字节,所以参数1在BP+6处) 参数2:在[BP+8]等 局部变量:在[BP-2], [BP-4]等位置 注意:具体的偏移量取决于调用约定和模式(16位/32位等)。 在子程序结束时,通常要恢复BPSPmov sp, bp ; 释放局部变量空间(将SP恢复到BP的位置) pop bp ; 恢复旧的BP ret ; 返回 另外,引用[2]中提到了CS:IP的作用,但这里我们主要关注BP寄存器。 总结:BP寄存器主要用于堆栈帧基址寻址,方便访问堆栈中的函数参数和局部变量。 §§相关问题§§ 1. BP寄存器和SP寄存器有什么区别? 2. 在32汇编中,BP寄存器(通常称为EBP)的用法与16位汇编有何异同? 3. 使用BP寄存器时,默认的段寄存器是什么? 4. 请举例说明如何使用BP寄存器访问函数参数和局部变量。</think>### BP寄存器的用途及使用方法 在x86汇编语言中,BP寄存器(Base Pointer Register)是16位架构中的关键基址指针寄存器,主要功能是为**堆栈段(SS)中的数据访问提供基址寻址**。其核心用途和操作规范如下: #### 、核心功能 1. **堆栈帧基址定位** BP寄存器默认与SS段寄存器配合使用(即`SS:BP`),专门用于访问当前函数的**堆栈帧(stack frame)**: - 保存函数参数(位于BP上方) - 访问局部变量(位于BP下方) - 典型寻址格式:`[BP + 偏移量]` 2. **与SP寄存器的区别** | 寄存器 | 指向位置 | 用途 | |--------|------------------|------------------------| | SP | 堆栈顶部 | 实时跟踪栈顶变化 | | BP | 堆栈帧固定基址 | 提供稳定的数据访问锚点 | #### 二、标准使用流程(函数调用场景) ```assembly ; 1. 函数入口:保存旧BP并建立新堆栈帧 push bp ; 保存调用者BP mov bp, sp ; 当前SP设为新BP(锚点) ; 2. 分配局部变量空间(可选) sub sp, 4 ; 预留4字节局部变量空间 ; 3. 访问数据 mov ax, [bp+4] ; 获取第个参数(位于BP上方) mov [bp-2], bx ; 存储到局部变量(位于BP下方) ; 4. 函数退出:恢复堆栈 mov sp, bp ; 释放局部变量空间 pop bp ; 恢复调用者BP ret ``` #### 三、寻址模式详解 - **参数访问**: 参数按**从右到左**顺序压栈,首个参数位于`[BP+4]`(假设16位模式,CALL指令压入2字节返回地址,PUSH BP压入2字节): ``` | 参数2 | [BP+6] | 参数1 | [BP+4] | 返回地址 | [BP+2] | 旧BP | [BP] <-- 当前BP指向此处 | 局部变量1 | [BP-2] ``` - **局部变量访问**: 通过负偏移量访问,如`[BP-2]` #### 四、注意事项 1. **段寄存器关联** BP默认使用SS段寄存器,无需显式指定(如`mov ax, [bp+4]`等价于`mov ax, ss:[bp+4]`)[^1]。 2. **32位扩展** 在32位模式下扩展为EBP寄存器,用法类似但偏移量变为4字节对齐。 3. **特殊限制** 在16位CPU中,BP不能直接用于算术运算(需通过其他寄存器中转)[^1]。 > **应用场景示例**:在中断处理中保存寄存器状态时,常用BP定位保存的AX/BX等寄存器,避免SP变动导致访问错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值