AT&T汇编学习总结一-汇编语言前言准备

  • 通用寄存器:当处理器处理数据时,通用寄存器用于临时存放数据。

    1. EAX:用于操作数和结果数据的累加器
    2. EBX:指向数据内存段中的数据的指针
    3. ECX:字符串和循环操作的计数器
    4. EDX:I/O指针
    5. EDI:用于字符串操作的目标的数据指针
    6. ESI:用于字符串操作的源的数据指针
    7. ESP:堆栈指针
    8. EBP:堆栈数据指针
  • 段寄存器:专门用于引用内存位置

    平坦内存模式:把全部系统内存表示为连续的地址空间

    分段内存模式:把系统内存划分为独立段的组。

    实地址模式

    1. CS:代码段
    2. DS:数据段
    3. SS:堆栈段
    4. ES:附加段指针
    5. FS:附加段指针
    6. GS:附加段指针
  • 指令指针寄存器:EIP寄存器、又称“程序计数器”,指令指针指向要执行的下一条指令。

  • 控制寄存器:五个控制寄存器用于确定处理器的操作模式、与当前正在执行的任务特性。不能直接访问控制寄存器中的值,但可以把控制寄存器包含的数据传送给通用寄存器。

    1. CR0控制操作模式和处理器状态的系统标志
    2. CR1当前没有使用
    3. CR2内存页面错误信息
    4. CR3内存页面目录信息
    5. CR4支持处理器特性和说明处理器特性能力的标志。
  • 标志:用来确定程序功能是否成功执行的唯一途径。

  • 状态标志:用来表明处理器进行的数学操作的结果。

    标志 位 名称志
    CF 0 进位标志
    PF 2 奇偶校验标志
    AF 4 辅助进位标志
    ZF 6 零标志
    SF 7 符号标志
    OF 11 溢出标志

  • 控制标志:用于控制处理器的特定行为,控制标志——DF标志、即方向标志,用于控制处理器处理字符串的方式。
  • 当DF标志被设置1时,字符串指令自动递减内存地址以便到达字符串的下一个字节; 当DF=0时,。。。递增。。。
  • 系统标志:用于控制操作系统级别的操作

    标志 位 名称
    TF 8 陷阱标志
    IF 9 中断使能标志
    IOPL 12和13 I/O特权级别标志
    NT 14 嵌套任务标志
    RF 16 恢复标志
    VM 17 虚拟8086模式标志
    AC 18 对准检查标志
    VIF 19 虚拟终端标志
    VIP 20 虚拟中断挂起标志
    ID 21 识别标志

    x87浮点单元(简称FPU)

    FPU寄存器 描述
    数据寄存器 用于浮点数数据的8个80位寄存器
    状态寄存器 报告FPU状态的16位寄存器
    控制寄存器 控制FPU精度的16位寄存器
    标志寄存器 描述8个数据寄存器的内容的16位寄存器
    FIP寄存器 指向下一条FPU指令的48位FPU指令指针
    FDP寄存器 指向内存中的数据的48位FPU数据指针
    操作码寄存器 保存FPU处理的最后指令的11位寄存器
    多媒体扩展(简称MMX)

    单指令多数据(SIMD):SIMD模型使用扩展的寄存器长度和新的数字格式来加快实施多媒体表现所需的复杂数字处理

    流化SIMD扩展(SSE)

    二. 相关的工具

    汇编器:把汇编语言源代码转化为处理器的指令码

    汇编语言源代码程序有三部分:

    操作码助记符

    数据段

    命令

    汇编器之间最大的区别是汇编命令

    MASM

    NASM

    gas(一个独特特性是能够创建不同于程序设计所在平台的平台的指令码,缺陷是不能在宿主系统上测试生成的程序)

    HLA(高级汇编器)

    连接器:链接目标代码的过程设计到解析程序代码中声明的所有定义好的函数和内存地址标签

    调试器大多数调试器提供的基本功能:

    在一个受控制的环境下运行程序,指定任何必须的运行时参数。

    在程序内的任何位置停止程序。

    检查数据元素,比如内存位置和寄存器

    在程序运行时改变程序中的元素以便帮助消除缺陷。

    编译器的工作是把高级语言转化为处理器能够执行的指令码。

    目标代码反汇编器

    简档器:能够跟踪每个函数在执行过程中被使用时花费了多长处理器时间。

    GNU汇编器(gas),具有为以下几种不同硬件平台汇编指令码的能力:

    VAX

    AMD 29K

    Hitachi H8/300

    Intel 80960

    M680x0

    SPARC

    Intel 80x86

    Z8000

    MIPS

    安装汇编器(在binutils包内)

    包 描述
    add2line 把地址转换为文件名和行号
    ar 创建、修改和展开文件存档
    as 把汇编语言代码汇编为目标代码
    c++filt 还原C++符号的过滤器
    gprof 显示程序简档信息的程序
    ld 把目标代码文件转换为可执行文件的连接器
    nlmconv 把目标代码转换为Netware Loadable Module格式
    objcopy 复制和翻译目标文件
    ranlib 生成存档文件内容的索引
    readelf 按照ELF格式显示来自目标文件的信息
    size 列出目标文件或者存档文件的段长度
    strings 显示目标文件中的可打印字符串
    strp 丢弃符号
    windres 编译Microsoft Windows资源文件
    nm 列出目标文件的符号
    objdump 显示来自目标文件的信息
    安装binutils包

    rpm: rpm -qa | grep binutils

    deb: dpkg -l | grep binutils

    使用汇编器gas,命令行可执行程序:as

    as命令行参数:

    参数 描述
    -a 指定输出中包含哪些清单
    -D 包含它用于向下兼容,但是被忽略
    –defsym 在汇编源代码之前定义符号和值
    -f 快速汇编,跳过注释和空白
    –gstabs 包含每行源代码的调试信息
    –gstabs+ 包含专门的gdb调试信息
    -I 指定搜索包含文件的目录
    -J 不警告带符号溢出
    -K 包含它用于向下兼容,但是被忽略
    -L 在符号表中保存本地符号
    –listing-lhs-width 设置输出数据列的最大宽度
    –listing-lhs-width2 设置连续行的输出数据列的最大宽度
    –listing-rhs-width 设置输出源代码的最大宽度
    –listing-cont-lines 设置输出的单一行在清单中输出的最大行数
    -o 指定输出目标文件的名称
    -R 把数据段合并进文本段
    –statistics 显示汇编使用的最大空间和总时间
    -v 显示as的版本号
    -W 不显示警告信息
    – 对于原文件使用标准输入
    操作码语法:Intel和AT&T语法区别

    AT&T使用$表示立即操作数,而Intel的立即操作数是不需要界定的。

    AT&T在寄存器名称前加上前缀%,而Intel无。在AT&T语法引用EAX寄存器写为%eax

    AT&T语法处理源和目标操作数时使用相反的顺序。把十进制4传送给EAX寄存器,AT&T语法:mov1 $4, %eax ,而Intel语法是mov eax, 4

    AT&T在助记符后面使用一个单独的字符来引用操作数中使用的数据长度,而Intel语法中数据长度被声明为单独的操作数。AT&T的指令mov1 $test, %eax 等同于Intel语法的mov eax, dword ptr test

    长调用和跳转使用不同语法定义段和偏移值。AT&T语法使用jmp section, offset,而Intel语法使用jmp section:offset

    GNU连接器ld用于把目标代码文件连接为可执行文件或者库文件。

    GNU编译器,GNU编译器集合为gcc,参数详解

    参数 描述
    -c 编译或者汇编代码,但是不进行连接
    -S 编译后停止,但是不进行汇编
    -E 预处理后停止,但是不进行编译
    -o 指定要使用的输出文件
    -v 显示每个编译阶段使用的命令
    -std 指定使用的语言标准
    -g 生成调试信息
    -pg 生成gprof制作简档要使用的额外代码
    -O 优化可执行代码
    -W 设置编译器警告信息级别
    -pedantic 按照C标准发布强制性诊断清单
    -I 指定包含文件的目录
    -L 指定库文件的目录
    -D 预定义源代码中的宏
    -U 取消任何定义了的宏
    -f 指定用于控制编译器行为的选项
    -m 指定与硬件相关的选项
    GNU调试器程序

    gcc使用参数

    参数 描述
    -b 设置远程调试时串行接口的线路速度
    -batch 以批处理模式运行
    -c 指定要分析的核心转储文件
    -cd 指定工作目录
    -d 指定搜索源文件的目录
    -e 指定要执行的目录
    -f 调试时以标准格式输出文件名和行号
    -nx 不执行.gdbinit文件的命令
    -q 安静模式——不输出介绍
    -s 指定符号的文件名
    -se 指定符号和要执行的文件名
    -tty 设置标准输入和输出设备
    -x 从指定的文件执行gdb命令
    在gdb命令提示下,调试命令:

    命令 描述
    break 在源代码中设置断点以便停止执行
    watch 设置监视点,当变量到达特定值时停止执行
    info 观察系统元素,比如寄存器、堆栈、内存
    x 检查内存位置
    print 显示变量值
    run 在调试器内开始程序的执行
    list 列出指定的函数或者行
    next 执行程序中的下一条指令
    step 执行程序中的下一条指令
    cont 从停止的位置继续执行程序
    until 运行程序,直到到达指定的源代码行

    GNU objdump程序:可以查看显示汇编语言代码,而且能够显示生成的原始指令码。-d把目标代码反汇编为指令码

    GNU简档器程序(gprof):用于分析程序的执行和确定应用程序中的“热点”在什么位置。“热点”是程序运行时需要最多处理时间的函数。一般为数学密集型的函数,但I/O密集型的函数也会增加处理时间。

    输出格式参数

    -p 不输出所有函数的一般简档,或者不显示指定函数的

    -g

    分析参数

    杂项参数

    三. 汇编语言程序范例

  • 程序的组成
    组成:
    数据段:是在可执行程序内声明指令码的地方,数据段声明带有初值的数据元素
    bss段:bss段声明使用零或者null值初始化的数据元素
    文本段
    定义段:GNU汇编器使用.section命令语句声明段。.section语句只使用一个参数——它声明段的类型。
    bss段总是应该安排在文本段之前,数据段可以移到文本段之后,但不标准。因需易阅读,将所有数据定义集中在源代码的开头。

            定义起始点:当汇编语言被转换为可执行文件时,连接器必须知道指令码的起始点是什么。对于使用分散在源代码各个位置的若干函数的更加复杂的程序。
    
            GNU汇编器声明一个默认标签或称标识符,用作应用程序的入口点。
    
            _start标签用作表明程序应从这条指令开始。若连接器找不到此标签,它会产生错误标签。
    
            若连接器找不到_start标签,它会试图查找程序的起始点,但对于复杂的程序,不能保证连接器能正确地作出猜测。
    
            可以使用_start之外的其他标签作为起始点。使用连接器的-e参数定义新的起始点的名称。
    
            除在应用程序中声明起始标签之外,还需要为外部应用程序提供入口点。这里使用.globl命令完成。
    
            .globl命令声明外部程序可以访问的程序标签。如果编写被外部汇编语言或者C语言程序使用的一组工具,就应该使用.globl命令声明每个函数段标签。
    
    
    
                 创建简单程序
    
                 CPUID指令是一条汇编指令,不容易从高级语言应用程序执行它。它是请求处理器的特定信息并且把信息返回到特定寄存器中的低级指令。
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值