本次笔记内容:
06.寻址模式与数据传输指令等

文章目录

  • 汇编程序员眼中的系统结构
  • 如何从C代码生产汇编代码
    • 如何装gcc?
    • 汇编语言数据格式
  • 第一条汇编指令实例
  • 数据传送指令(mov)
    • 语法与操作数类型
    • 不同的操作数类型组合
  • 简单的寻址模式
    • 间接寻址
    • 基址+偏移量寻址
    • 寻址模式使用实例
    • 变址寻址

本次笔记从C语言的经典代码出发,学习汇编语言的接口作业。

汇编程序员眼中的系统结构

在用户层编写程序(不涉及kernel,因此也不涉及保护模式等),x86系统看起来是下述结构:

  • CPU是由PC、Registers、Condition Codes构成:
    • 指令集存器(PC Program Counter),存储下一条指令的地址,在x86-32中用EIP表示,在x86-64中用RIP表示;
    • 寄存器堆;
    • 条件码,用于存储最近执行指令的结果状态信息,用于条件跳转指令的判断。
  • 存储器(Memory),即存储器,包括Object Code、Program Data、OS Data、Stack:
    • 以字节编码的连续存储空间;
    • 存放程序代码、数据、运行栈以及操作系统数据。

CPU为Memory提供指令,Memory将Data和Instructions传输给CPU。

如何从C代码生产汇编代码

C代码

int sum(int x, int y)
{int t = x + y;return t;
}

命令行输入:

gcc -O2 -S code.c
  • -O2表示优化,等级为2(-O3太激进);
  • -S表示生产汇编文件;
  • 生产汇编文件code.s。

对应的x86-32汇编,AT&T汇编格式(与Intel Microsoft汇编格式不同):

sum:pushl %ebpmovl %esp, %ebpmovl 12(%ebp), %eaxaddl 8(%ebp), %eaxmovl %ebp, %esppopl %ebpret

如何装gcc?

  • linux自带;
  • Windows可以去下载Cygwin(Get that Linux feeling on Windows)。

汇编语言数据格式

C声明 Intel数据类型 汇编代码后缀 大小(字节)
char 字节 b 1
short w 2
int 双字 l 4
long int 双字 l 4
long long int - - 4
char * 双字 l 4
float 单精度 s 4
double 双精度 l 8
long double 扩展精度 t 10/12

b即byte,w即word;因为是32位机型,long int与int同,long long int没有。

在x86-32中,使用“字(word)”来表示16位整数类型,“双字”表示32位。汇编语言中没有数据类型,一般采用汇编指令的后缀来进行区分。

第一条汇编指令实例

C代码:

int t = x + y;

为两个整数(32位)相加。

汇编代码:

addl 8(%ebp), %eax
  • 两个32位整数相加:
    • “l”后缀表示是双字运算;
    • 无符号/带符号整数加法运算的指令是一样的。

类似于表达式 x += y或者:

int eax;
int *ebp;
eax += ebp[2];

操作数:

  • x:Register eax
  • y:Memory M[ebp+8];
  • t:Register eax

把x与y加起来,放在t中(结果存于eax中)。

机器码:

0x401046: 03 45 08

3-字节指令。

数据传送指令(mov)

语法与操作数类型

数据传送(AT&T语法)

movl Source, Dest:

  • 将一个“双字”从Source移到Dest;
  • 常见指令。

要注意,对于很多指令,在MIPS或Intel Microsoft中Soure, Dest位置是相反的。

允许的操作数类型

  • 立即数:常整数
    • 如:$0x400, $-533
    • 应注意一定要有$符号
    • 可以被1,2或4个字节来表示
  • 寄存器:8个通用寄存器之一
  • 存储器:四个连续字节,支持多种访存寻址模式

不同的操作数类型组合

 Source  Dest    例子              类似的C语言表示
movl {Imm {Reg      movl $0x4, %eax     temp = 0x4;Mem     movl $-147, (%eax)  *p = -147;}Reg {Reg        movl %eax, %edx     temp2 = temp1;Mem      movl %eax, (%edx)   *p = temp;}Mem {   Reg     movl (%eax), %edx   temp = *p;}
}

注意:

  • 带不带括号意思不同;
  • movl $-147, (%eax)表示eax中的值作为地址,把-147这个值放到eax的值所代表的地址的地址空间中去;
  • 如果没有美元符号,则把数字当成地址;
  • 不能两个操作数都为内存地址!

简单的寻址模式

间接寻址

(R) : Mem[Reg[R]]

表示寄存器R指定内存地址。

movl (%ecx), %eax

基址+偏移量寻址

D(R) : Mem[Reg[R] + D]
  • 寄存器R指定内存起始地址;
  • 常数D给出偏移量。
movl 8 (%ebp), %edx

表示,取ebp的值,加上8,作为地址,取出连续4个byte来(因为mov后缀为l),放在edx中。

寻址模式使用实例

void swap (int *xp, int *yp)
{int t0 = *xp;int t1 = *yp;*xp = t1;*yp = t0;
}

swap:

pushl %ebp
movl %esp, %ebp
pushl %ebx
// 以上为Set Up
movl 12(%ebp), %ecx
movl 8(%ebp), %edx
movl (%ecx), %eax
movl (%edx), %ebx
movl %eax, (%edx)
movl %ebx, (%ecx)
// 以上为Body
movl -4(%ebp), %ebx
movl %ebp, %esp
popl %ebp
ret
// Finsih

如上图,以ebp作为基准。

如上图,假设现在已知ebp存储0x104:

  • 第一条,ebp作为基址(0x104),加12偏移量,即0x110(注意是16进制)的值0x120取出来,并将0x120值赋给exc;
  • 第二条,将ebp作为基址,加8偏移量,即0x10c的值0x120取出来,并将其赋给edx;
  • 第三条,即将exc的值作为地址,将地址对应的值取出来,赋给%eax;
  • 之后同理。

心得:movl (%ecx), %eax表示将ecx的值作为地址,并将其地址对应的值取出来,赋给eax;即,movl其实是对两个地址对应的数值(可是立即数、可是地址)进行操作。

变址寻址

常见形式:

D(Rb, Ri, S) : Mem[Reg[Rb] + S * Reg[Ri]]
  • D为常量(地址偏移量);
  • Rb为基址寄存器:8个通用寄存器其之一;
  • Ri为索引寄存器:%esp不作为索引寄存器,一般%ebp也不做这个用途;
  • S为比较因子1,2,3或8.

其他变形还有:

(Rb, Ri) : Mem[Reg[Rb] + Reg[Ri]]
D(Rb, Ri)   : Mem[Reg[Rb] + Reg[Ri] + D]
(Rb, Ri, S) : Mem[Reg[Rb] + S * Reg[Ri]]

【汇编语言与计算机系统结构笔记05】汇编的系统结构,从C代码生产汇编代码,一个具体的、经典的数据传送指令(mov)实例与分析相关推荐

  1. 数据传送指令----mov(笔记)ATT

    数据传送指令--mov 基本概念 将数据从一个位置复制到另一个位置:mov类有四条指令组成:movb.movw.movl和movq:主要区别是传送数据的大小不同,分别是1. 2. 4和8字节. mov ...

  2. 计算机组成原理学习笔记————计算机指令,MIPS指令集,存储器操作数,数据传送指令,取数存数指令

    计算机语言 现在计算机编程常用的语言是C,C++,Java等高级语言,但计算机第层是将高级编程语言的代码编译成二进制代码形式的指令才能执行.所以计算机语言中的基本单词是二进制形式的指令,一台计算机的全 ...

  3. 8086到80386汇编数据传送指令的扩展

    80386及以上汇编的数据传送指令如下: MOV     传送字或字节.   MOVSX   先符号扩展,再传送.   MOVZX   先零扩展,再传送.   PUSH    把字压入堆栈.   PO ...

  4. 计算机组成原理xchg,8088数据传送指令-计算机组成原理与汇编语言-电子发烧友网站...

    3.2.1 数据传送指令 1. MOVOPRD1,OPRD2 MOV是操作码,OPRD1和OPRD2分别是目的操作数和源操作数.该指令可把一个字节或一个字操作数从源地址传送到目的地址. 源操作数可以是 ...

  5. 汇编语言--数据传送指令

    8086CPU的数据传送指令 mov.push.pop.pushf.popf.xchg 等都是数据传送指令,这些指令实现寄存器和内存.寄器和寄存器之间的单个数据传送

  6. 汇编语言||基本传送指令MOV的用法详解

    MOV指令 MOV指令,能实现以下操作: CPU内部寄存器之间数据的任意传送(除了码段寄存器CS和指令指针IP以外). 立即数传送至CPU内部的通用寄存器组(即AX.BX.CX.DX.BP.SP.SI ...

  7. 汇编语言数据传送指令之通用数据传送类指令

    文章目录 1.通用数据传送类指令 1. 1)Mov reg/mem,imm//立即数传送 1. 2)Mov reg/mem/seg,reg//寄存器传送] 1. 3)Mov reg/seg,mem// ...

  8. 【Android 逆向】x86 汇编 ( call 子函数调用指令 | jmp 跳转指令 | lea 加载指令 | mov 数据传送指令 )

    文章目录 一.call 子函数调用指令 二.jmp 跳转指令 三.lea 加载指令 四.mov 数据传送指令 总结 一.call 子函数调用指令 call 指令是 子函数调用指令 , 调用的指令的下一 ...

  9. 微机原理笔记——数据传送指令

    数据传送指令 通用数据传送指令 传送指令MOV 格式 MOV DST,SRC 功能 将一个源操作数送到目的操作数 说明 1.DST是目的操作数,可以是寄存器,存储器,累加器 SRC是源操作数,可以是寄 ...

最新文章

  1. mysql半连接_mysql表的半连接,反连接导致的mysql性能优化剖析
  2. 超详细单机版搭建hadoop环境图文解析
  3. 【前沿技术】Facebook 硬件负责人,带摄像头的智能眼镜将在 10 年内成为常态
  4. 11款新品,一切为了落地!商汤:普惠AI的时代,来了
  5. 复数特征值求特征向量_深刻地认识特征值
  6. 3D打印攻破无人车激光雷达,这个奇怪的盒子它看不见
  7. python web为什么不火-编程语言里的明星:Python为什么突然不火了?
  8. 移动端省际联动插件mobiscroll
  9. trove mysql 镜像_trove 基于 centos7 制作 mysql5.6 镜像
  10. Python 操作 redis
  11. 关于流(文件)的输入,输出与调用(fprintf,fscanf)
  12. 读书笔记《Java开发技术-在架构中体验设计模式和架构之美》
  13. linux文件IO的操作
  14. 02WCF初识:ServiceEndpoint
  15. 面试之C#--垃圾回收器什么时候回收?
  16. Ansible#Typora-Ansible笔记
  17. 单片机60秒秒表c语言,基于51单片机的60秒,秒表计时器
  18. 安卓WebView的那些坑
  19. iOS开发之加载、滑动翻阅大量图片优化解决方案
  20. 一起赚美金:经典Niche站变现模式分析(1)

热门文章

  1. zkfc 异常退出问题,报错Received stat error from Zookeeper. code:CONNECTIONLOSS
  2. c#执行插入sql 时,报错:异常信息:超时时间已到。在操作完成之前超时时间已过或服务器未响应
  3. UTF-8的CSV文件中文乱码问题解决办法
  4. mysql 如何解决字段不区分大小写的问题
  5. 编写一个程序,从10亿个数字的数组中找出100个最大的数字
  6. Mipmap drawables图标
  7. Array.prototype.slice.call()如何工作?
  8. 用java写猜拳游戏,Java写人机猜拳游戏(可扩展其他游戏或其他参与者)
  9. AT指令:AT+CMGF
  10. 问答| car-like robot为何需要设置多个坐标系?