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

(学习笔记)3.5 算术和逻辑操作(3.5.1 加载有效地址)

文章目录

  • 线索栏
  • 笔记栏
    • 1. 整数和逻辑操作概述
    • 2. 加载有效地址指令 (leaq) 详解
      • 1)关键理解
      • 2)算术妙用
    • 3. 函数 scale的LEA实现分析
    • 4.练习题
      • 练习题3.6
      • 练习题3.7
  • 总结栏

线索栏

  1. x86-64的整数和逻辑操作分为哪四组?每组的特点是什么?
  2. LEA指令 (leaq)​ 的特殊之处是什么?它与 movq指令有何本质区别?
  3. LEA指令除了计算有效地址,还有什么巧妙的用途?它能执行哪些算术运算?
  4. 如何使用LEA指令的寻址模式 Imm(r_b, r_i, s)来简洁地表示形如 a + k*b + c的线性表达式?
  5. 一元操作和二元操作的指令操作数分别位于哪里?(目的操作数 vs 源/目操作数)
  6. 移位操作的移位量 k可以来自哪里?
  7. (练习题3.6)如何计算给定 leaq指令表达式的值?
  8. (练习题3.7)如何从使用LEA指令的汇编代码反推其实现的原始C语言算术表达式?

笔记栏

1. 整数和逻辑操作概述

如图3-10所示,x86-64的整数和逻辑操作分为四组:

(1)注意:大多数操作都有对应不同数据大小(字节、字、双字、四字)的指令类(如addb, addw, addl, addq),唯独 leaq没有其他大小变体,它固定操作四字(8字节)。
(2)操作数顺序:ATT格式汇编中,操作顺序与图3-10表格中的数学描述相反。例如,addq %rax, %rbx的效果是 %rbx = %rbx + %rax。

2. 加载有效地址指令 (leaq) 详解

leaq S, D指令的效果是:D ← &S,即将源操作数 S 的有效地址写入目的操作数 D。

1)关键理解

(1)形式上:leaq指令的源操作数 S 看起来像一个内存引用(如 7(%rdi,%rsi,4))。
(2)实际上:它并不访问该内存地址去读取数据,而是直接计算出这个内存引用格式所代表的有效地址(一个数值),并将这个计算结果存入目的寄存器 D。
(3)本质:它是 movq指令的一个变体,但移除了内存访问步骤,只进行地址计算。

2)算术妙用

因为有效地址的计算公式是 Addr = Imm + R[r_b] + R[r_i] * s,这正好可以用于计算形如 c + a + k*b的线性表达式,其中 c是立即数,a和 b是寄存器值,k是比例因子(1,2,4,8)。
示例:leaq 7(%rdx, %rdx, 4), %rax计算 5 * %rdx + 7并存到 %rax。

3. 函数 scale的LEA实现分析

(1)C函数:

longscale(longx,longy,longz){longt=x+4*y+12*z;returnt;}

(2)汇编实现(xin %rdi, yin %rsi, zin %rdx):

scale:leaq(%rdi,%rsi,4),%rax # rax=x+4*yleaq(%rdx,%rdx,2),%rdx # rdx=z+2*z=3*zleaq(%rax,%rdx,4),%rax # rax=(x+4*y)+4*(3*z)=x+4*y+12*z ret

4.练习题

练习题3.6


练习题3.7

scale2:leaq(%rdi,%rdi,4),%rax # rax=x+4*x=5*xleaq(%rax,%rsi,2),%rax # rax=5*x+2*yleaq(%rax,%rdx,8),%rax # rax=(5*x+2*y)+8*z ret


总结栏

本节是理解x86-64计算能力的核心,引入了基础的算术与逻辑指令,并深入剖析了 leaq这一多功能指令。

  1. 四组操作:LEA、一元、二元、移位构成了整数运算的基础工具箱。必须牢记二元和移位操作会修改目的操作数,而一元操作数同时作为源和目的。
  2. LEA指令的双重角色:
    (1) 本意:加载有效地址,用于生成指针。
    (2) 妙用:由于其地址计算机制(Imm + Rb +Ri*s),它常被编译器用作一个高效的、能执行常数乘法(因子为2,4,8)和加法的算术单元,而无需动用真正的乘法指令。这是编译器优化中的常见技巧。
  3. 从公式到代码:理解LEA指令的关键在于将汇编中的内存引用格式 Imm(r_b, r_i, s)直接视为一个数学表达式 Imm +R[r_b] + R[r_i]*s来计算其值,这个值就是目的寄存器得到的结果。
  4. 逆向工程训练:练习题3.6和3.7强化了正向计算和反向推导的能力。通过练习,应能熟练地在LEA指令格式与其所表示的线性表达式之间进行转换,这是阅读和理解编译器生成的算术运算代码的基本功。

核心启示:leaq指令体现了计算机系统中“抽象”与“重用”的智慧。一个为地址计算设计的硬件特性,因其数学模型恰好匹配一类常见的算术运算,而被软件(编译器)创造性重用,从而提升了效率。理解这种硬件与软件的相互影响,是掌握系统编程的关键。

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

相关文章:

  • 华为 MetaERP 是面向跨国企业、支持多组织、多账套、多币种、多会计政策的全栈自主可控国产 ERP,已在华为全球 170 + 国家 / 地区、88 家子公司完成 Oracle 替换,是国产替代跨国
  • VS Code 的安装与如何搭建C/C++开发环境?
  • 高达2070TFLOPS算力|腾视科技基于NVIDIA Jetson Thor系列模组,重磅推出全栈AI边缘智算大脑解决方案
  • 骏马奔腾,服务暖心——2026年深圳市专业殡仪服务机构甄选指南与客观推荐 - 深度智识库
  • 网络安全入门 arp断网
  • 2026装修行业全案投流全解析 精准选对服务商攻略 - 品牌测评鉴赏家
  • 安卓15_ROM修改定制化_____修改settings设置app的常用的修改定制项目 终结篇
  • 极简致美,笃行致远——宏洛图2025-2026化妆品及保健品包装设计美学实践 - 宏洛图品牌设计
  • 千问 文心 元宝 Kimi怎么分享整个对话
  • loTDB数据库
  • PostgreSQL 技术日报 (3月11日)|4库合一性能提升350倍与内核新讨论
  • 算法题复盘
  • 价值十亿美元的三句话:从“漂移”到“确定性”(Drift to Determinism,DriDe)
  • Agentic Model落地指南:以DeepMiner商业数据分析智能体为例,解读如何构建可信、可用的企业级AI系统
  • OpenClaw安装完全手册:搞定“龙虾”顺便带走5个超强插件!
  • 电路中的数学公式:一阶电路基本概念,暂态响应与稳态响应
  • 真正的编程能力是会调试 —— 其它都是复制粘贴
  • React 项目运用 RxJS 设置节流
  • 【嵌入式Linux】应用开发基础总结
  • 别再找Python+YOLO教程了!Java+YOLOv11保姆级教程:环境搭建→模型加载→推理全流程,附我踩过的5个血泪坑
  • 保姆级网络安全入门教程:手把手带你从小白进阶大神(附学习资源)
  • OpenClaw机器人引爆天网,首次拥有记忆,逆天了!
  • Java毕业设计-基于springboot框架的医院预约挂号系统项目实战(附源码+论文)
  • 运维岗干久了会怎么样?为什么说运维工程师做不长久,做两年就赶快转转岗?
  • 【大数据存储与管理】分布式数据库HBase:02 HBase访问接口
  • 短剧SAAS系统 vs 私有化部署:内容方/创业者该如何选择?
  • 〘 3-2 〙软考高项 | 第10章:项目进度管理(下)
  • 非科班转网络安全完整指南:没有天赋,只有系统方法,年薪50万+实战路径
  • 网络安全自学路线图:从0基础到实战专家,这一篇就够了!(超详细)
  • 【算法二十】 1​​​​​​​1​​​​​​​4. 寻找两个正序数组的中位数 153. 寻找旋转排序数组中的最小值