当前位置: 首页 > news >正文

寒假学习笔记1.15

一、 扩展指令集实现

  1. 算术运算扩展
    减法指令(SUB)
    python
    def sub(reg, source):
    """减法运算:reg = reg - source"""
    if source in REGISTERS:
    value = REGISTERS[source]
    elif source.isdigit():
    value = int(source)
    else:
    raise ValueError("无效源操作数")

    设置标志位

    FLAGS['CF'] = 1 if value > REGISTERS[reg] else 0 # 借位标志
    FLAGS['ZF'] = 1 if REGISTERS[reg] - value == 0 else 0 # 零标志

    REGISTERS[reg] -= value
    乘法指令(MUL)和除法指令(DIV)
    python
    def mul(reg, source):
    """乘法运算:reg = reg * source"""
    if source in REGISTERS:
    value = REGISTERS[source]
    elif source.isdigit():
    value = int(source)
    REGISTERS[reg] *= value

def div(reg, source):
"""除法运算:reg = reg // source"""
if source in REGISTERS:
value = REGISTERS[source]
elif source.isdigit():
value = int(source)
if value == 0:
raise ValueError("除零错误")
REGISTERS[reg] //= value
2. 逻辑运算指令
与运算(AND)、或运算(OR)、非运算(NOT)
python
def and_op(reg, source):
"""按位与运算"""
if source in REGISTERS:
value = REGISTERS[source]
elif source.isdigit():
value = int(source)
REGISTERS[reg] &= value
FLAGS['ZF'] = 1 if REGISTERS[reg] == 0 else 0

def or_op(reg, source):
"""按位或运算"""
if source in REGISTERS:
value = REGISTERS[source]
elif source.isdigit():
value = int(source)
REGISTERS[reg] |= value
FLAGS['ZF'] = 1 if REGISTERS[reg] == 0 else 0

def not_op(reg):
"""按位非运算"""
REGISTERS[reg] = ~REGISTERS[reg]
二、 栈机制实现

  1. 栈内存分配
    python

扩展内存模型,分配栈空间

MEMORY_SIZE = 256
STACK_SIZE = 64
MEMORY = [0] * MEMORY_SIZE # 0-191为通用内存,192-255为栈空间

栈指针寄存器

REGISTERS['SP'] = MEMORY_SIZE - 1 # 栈指针指向栈顶
REGISTERS['BP'] = MEMORY_SIZE - 1 # 基址指针
2. 栈操作指令
PUSH(压栈)
python
def push(source):
"""将数据压入栈"""
if source in REGISTERS:
value = REGISTERS[source]
elif source.isdigit():
value = int(source)

# 栈从高地址向低地址增长
MEMORY[REGISTERS['SP']] = value
REGISTERS['SP'] -= 1# 栈溢出检查
if REGISTERS['SP'] < MEMORY_SIZE - STACK_SIZE:raise MemoryError("栈溢出")

POP(出栈)
python
def pop(target):
"""从栈中弹出数据到目标寄存器"""
# 栈下溢检查
if REGISTERS['SP'] >= MEMORY_SIZE - 1:
raise MemoryError("栈下溢")

REGISTERS['SP'] += 1
value = MEMORY[REGISTERS['SP']]if target in REGISTERS:REGISTERS[target] = value
else:raise ValueError("目标必须是寄存器")

三、 子程序调用机制

  1. CALL和RET指令
    python
    def call(label):
    """调用子程序"""

    保存返回地址(下一条指令的地址)

    return_address = PC + 1
    push(str(return_address))

    跳转到子程序

    if label in LABELS:
    global PC
    PC = LABELS[label] - 1 # -1因为执行后会PC+1
    else:
    raise ValueError(f"未定义的标签: {label}")

def ret():
"""从子程序返回"""
# 从栈中弹出返回地址
pop('AX') # 临时存储到AX
global PC
PC = REGISTERS['AX'] - 1 # -1因为执行后会PC+1
2. 栈帧管理
python

进入子程序时保存基址指针并建立新栈帧

def enter():
"""进入子程序,建立新栈帧"""
push('BP') # 保存原BP
REGISTERS['BP'] = REGISTERS['SP'] # 新栈帧基址

def leave():
"""离开子程序,恢复原栈帧"""
REGISTERS['SP'] = REGISTERS['BP'] # 恢复栈指针
pop('BP') # 恢复原BP
四、 综合示例程序

  1. 计算阶乘的子程序
    python

汇编程序:计算5的阶乘

程序 = [
'MOV AX, 5', # 设置参数
'CALL FACTORIAL', # 调用阶乘函数
'MOV [0], AX', # 存储结果
'HLT', # 停机

# 阶乘子程序
'FACTORIAL:',
'PUSH BP',        # 保存原BP
'MOV BP, SP',     # 建立新栈帧
'PUSH BX',        # 保存BX'MOV BX, AX',     # 备份参数
'CMP AX, 1',      # 比较AX和1
'JLE BASE_CASE',  # 如果AX<=1,跳转到基本情况# 递归调用
'SUB AX, 1',      # AX = n-1
'CALL FACTORIAL', # 递归调用
'MUL AX, BX',     # AX = n * factorial(n-1)
'JMP END_FACT','BASE_CASE:',
'MOV AX, 1',      # factorial(1) = 1'END_FACT:',
'POP BX',         # 恢复BX
'POP BP',         # 恢复BP
'RET'             # 返回

]
2. 函数调用中的栈变化
text
初始状态:
SP=255, BP=255

执行CALL FACTORIAL后:
SP=254, MEMORY[255]=返回地址

执行PUSH BP后:
SP=253, MEMORY[254]=原BP值

执行MOV BP, SP后:
BP=253 (新栈帧基址)

执行PUSH BX后:
SP=252, MEMORY[253]=BX的原值

...递归调用会继续压栈...

每次RET返回时,会逆向恢复栈状态

http://www.jsqmd.com/news/263777/

相关文章:

  • 机器学习优化投资组合压力测试
  • AI架构师进阶:模型评估的5大核心方法
  • 一款自动化的403/401绕过测试工具
  • 基于Comsol软件的激光熔覆熔池流动数值模拟:考虑马兰戈尼对流及元素影响下表面张力系数的转变研究
  • 英语_阅读_Baidus robotaxi_待读
  • XSS 漏洞练习靶场,覆盖反射型、存储型、DOM 型、SVG、CSP、框架注入、协议绕过等多种场景
  • 费雪的行业领导者理论:寻找市场冠军
  • IP反查工具,能够快速查询指定IP/域名关联的所有网站
  • 详细介绍:【杂谈】-边缘计算竞赛:人工智能硬件缘何超越云端
  • 学长亲荐10个AI论文写作软件,MBA论文轻松搞定!
  • java求职学习day49
  • ubuntu 实现远程登录
  • 挖掘 0-Day 漏洞:AFL++ 模糊测试实战,给开源图像库 (libpng) 找一个致命 Crash
  • 布隆过滤器进阶:布谷鸟过滤器 (Cuckoo Filter) 是如何支持“删除”操作的?
  • Codeforces Round 1073 Div1 + Div2 部分题目题解
  • web入门111-120
  • 第 485 场周赛Q1——3813. 元音辅音得分
  • 恶意代码分析:在沙箱中运行勒索病毒,用 IDA Pro 逆向它的加密逻辑
  • 导师严选2026 AI论文网站TOP8:继续教育写作全攻略
  • LLM 推理加速:深入 vLLM 源码,揭秘 PagedAttention 如何让吞吐量提升 20 倍?
  • 完整教程:【Go/Python/Java】基础语法+核心特性对比
  • 数据交易中的数据质量评估方法
  • 数据结构3.0 栈、队列和数组
  • 算子优化实战:手写 Triton Kernel,将 LayerNorm 算子的执行时间压缩 50%
  • 深度测评自考必备一键生成论文工具TOP8
  • Linux实操篇
  • 51单片机智能遮阳篷窗户帘衣架蓝牙APP光雨滴检测41(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • Java 并发探秘:JCTools 源码剖析,为什么 Netty 放弃 JDK 自带队列而选择 MpscArrayQueue?
  • todo
  • Go 调度器 (GMP) 揭秘:从汇编角度看 Goroutine 是如何实现“协程切换”的?