【汇编语言】程序格式

程序格式


文章目录

  • 程序格式
    • 一、处理器指令格式
      • (1)处理器指令
        • 1.操作码(Opcode)
        • 2.操作数(Operand)
      • (2)数据传送指令
      • (3)指令格式
    • 二、汇编语言语句格式
      • (1)汇编语言语句
      • (2)汇编语句成分
        • 1.标号与名字
        • 2.助记符
        • 3.操作数和参数
        • 4.注释和分隔符
      • (3)良好的语句格式
    • 三、源程序框架
      • (1)包含伪指令INCLUDE
      • (2)段的简化定义
      • (3)程序的开始和结束
    • 四、第一个程序:信息显示
      • (1)输入输出子程序库
      • (2)信息显示的汇编语言源程序
      • (3)常用输出子程序
      • (4)常用输入子程序

一、处理器指令格式

(1)处理器指令

程序用程序设计语言编写,由指令构成; 指令由操作码和操作数(地址码)组成。

1.操作码(Opcode)

表明处理器执行的操作

  • 例如数据传送、加法运算、跳转等操作
  • 汇编语言使用指令助记符表示
2.操作数(Operand)

是参与操作的数据对象

  • 主要以寄存器名或地址形式指明数据的来源
  • 汇编语言使用寄存器、常量、变量等形式表示

(2)数据传送指令

传送指令的助记符:MOV(取自Move)
将数据从一个位置传送到另一个位置

  • 类似高级语言的赋值语句:mov dest,src

  • 源操作数src: 被传送的数据或数据所在的位置

  • 目的操作数dest: 数据将要传送到的位置

mov eax, 100 ;EAX←100 (常量)
mov eax, dvar ;EAX←dvar (变量)
mov eax,ebx ;EAX←EBX(寄存器)

(3)指令格式

IA-32 处理器的指令系统采用可变长度指令格式,指令编码非常复杂 这一方面是为了兼容8086 指令,另一方面是为了向编译程序提供更有效的指令。

IA-32 处理器的指令包括:可选的指令前缀、 1~3 字节的主要操作码 可选的寻址方式域(包括ModR/M SIB 字段)、可选的位移量和可选的立即数 指令前缀和主要操作码字段对应指令的操作码部分,其他字段对应指令的操作数部分,

  • 指令前缀

    • 指令前缀 (Prefix) 是指令之前的辅助指令(也称前缀指令),用千扩展指令功能
    • 每个指令之前可以有 0-4 个前缀指令,顺序任意,并可以分成四组:
      • 第一组有 LOCK 前缀指令(指令代码为 FOH), 用于控制处理器总线产生锁定操作。
      • 第二组主要是段超越 (Segment Override) 前缀指令,用于明确指定数据所在段。
      • 第三组是操作数长度超越 (Operand- size Override) 前缀,指令代码为 66H 。
      • 第四组是地址长度超越 (Address- size Override) 前缀,指令代码为 67H
  • 操作码

    指令执行的操作(如加、减、传送等)编码称为操作码部分

    • 可选的指令前缀(用于扩展指令功能,0~4字节)
    • 1~3字节的主要操作码
  • 操作数

    • 可选的寻址方式域(包括ModR/M和SIB字段,0或1字节)
    • 可选的位移量(0、1、2或4字节)
    • 可选的立即数(0、1、2或4字节)

【汇编语言】程序格式_第1张图片

二、汇编语言语句格式

(1)汇编语言语句

  • 执行性语句:表达处理器指令,实现功能

    表达处理器指 的语句称为执行性语 执行性语句汇编后对应一条指令代码 由处理器指令组成的代码序列是程序设计的主体。

    标号: 硬指令助记符操作数, 操作数 ;注释

  • 说明性语句:表达伪指令,控制汇编方式

    表达汇编程序命令的语句称为说明性(指 性)语句 说明性语句指示源程序如何汇编、变量如何定义、过程如何设置 相对于真正的处理器指(也称为真指令 硬指令),汇编程序命 也称为伪指令 (Pseudoinstruction) 、指示符 (Dire tive) 。

    名字 伪指令助记符 参数, 参数, … ;注释

【汇编语言】程序格式_第2张图片

(2)汇编语句成分

1.标号与名字

标号与名字是用户定义的标识符 (取名原则类似高级语言,但默认不区别大小写字母)

标识符(Identifier):

  • 最多由31个字母、数字及规定的特殊符号组成
  • 不能以数字开头
  • 一个源程序中,用户定义的每个标识符必须唯一
  • 不能是保留字(Reserved Word)=关键字(KeyWord)
  • 标号
    执行性语句中

    • 冒号分隔
    • 表示处理器指令在主存中的逻辑地址
    • 指示分支、循环等程序的目的地址
  • 名字
    说明性语句中

    • 空格或制表符分隔
    • 变量名、段名、子程序名等
    • 反映变量、段和子程序等的逻辑地址
2.助记符

助记符 (Mnemonics) 是帮助记忆指令的符号,反映指令的功能

  • 硬指令助记符表示处理器指令
  • 伪指令助记符表达一个汇编命令

汇编语言源程序中使用最多的字节变量定义伪指令,其助记符是 BYTE (或 DB, 取自 Define Byte), 功能是在主存中分配若干的存储空间,用于保存变量值,该变量以字节为单位存取。

  • 例:用 BYTE 伪指令定义一个字符串,并使用变量名 MSG 表达其在主存中的逻辑地址:

    msg byte'Hello,Assembly !',13,10,0
    
  • 例:以用一个 MASM 操作符 OFFSET 获得其偏移地址,保存到 EAX 寄存器:

    mov eax , offset msg ;EAX 获得 MSG 的偏移地址
    
3.操作数和参数

处理器指令的操作数:表示参与操作的对象

  • ►具体的常量
  • ►保存在寄存器的数据
  • ►保存在存储器中的变量
  • ►逗号前常是目的操作数,逗号后常是源操作数

伪指令的参数:

  • ►常量、变量名、表达式等
  • ►可以有多个,参数之间用逗号分隔
4.注释和分隔符
  • 注释

    • ►对指令或程序进行说明,使用英文或中文均可
    • ►汇编程序不对它们做任何处理
    • ►注释利于阅读,应养成书写注释的好习惯
    • ►注释可以用分号开头,占用一个语句行
  • 分隔符

    • ►分隔符都是英文标点
    • ►标号后的冒号
    • ►注释前的分号
    • ►操作数间和参数间的逗号
    • ►分隔其他部分采用一个或多个空格或制表符

(3)良好的语句格式

  • 标号和名字从首列开始书写
  • 通过制表符对齐指令助记符和注释部分
  • 助记符与操作数和参数之间用空格或者制表符分隔

三、源程序框架

include io32.inc       ;包含32位输入输出文件
        .data          ;定义数据段
        …              ;数据定义(数据待填)
        .code          ;定义代码段
start:                 ;程序执行起始位置
        …              ;主程序(指令待填)
        exit 0         ;程序正常执行终止
        …              ;子程序(指令待填)
       end start       ;汇编结束

(1)包含伪指令INCLUDE

MASM 提供源文件包含伪指令 INCLUDE, 用于声明常用的常量定义 过程说明 共享的子程序库等内容(相当于 C和C++语言中包含头文件的作用)

1032. INC前三个个语句是:

. 686 
.model flat,stdcall 
option casemap: none
  • 第一个语句是 MASM 汇编程序的处理器选择伪指令,声明采用 Pentium Pro (原被称为 80686处理器)支待的指令系统
  • 第二个语句 “.MODEL” 确定程序采用的存储模型 编写(Windows 操作系统下的 32 位程序时,只能选择 FLAT 平展模型)。
  • 选项伪指令 “OPTION CASEMAP: NONE” 告知 MASM 要区分标识符的大小写。

(2)段的简化定义

对应存储空间的分段管理,用汇编语言编程时也常将源程序分成代码段、数据段或堆栈段。需要独立运行的程序必须包含一个代码段,并指示程序执行的起始位置
需要执行的可执行性语句必须位千某一个代码段内,说明性语句通常安排在数据段,或根据需要位于其他段。

  • ►数据段定义伪指令

    • .DATA ;创建一个数据段
  • ►代码段定义伪指令

    • .CODE ;创建一个代码段
  • ►堆栈段定义伪指令

    • .STACK ;创建一个堆栈段

      通常堆栈由 Windows 操作系统维护,用户不必设置,但如果程序使用的堆栈空间较大,也可以设置

(3)程序的开始和结束

  • 程序开始执行的位置

    程序模板中定义了 个标号 START (也可以使用其他标识符),在最后的汇编结束 END指令需要利用它作为参数,以指明程序开始执行的位置

    • 使用一个标号(例如:START)
    • 作为汇编结束END伪指令的参数
  • 应用程序执行终止

    应用程序执行终止,应该将控制权交还操作系统 另外,还可以给操作系统提供一个返回代码,可以用语句 "EXIT 实现此功能,其中数值0就是返回代码 ,通常用 表示执行正确

    • 语句“EXIT 0”终止程序执行
    • 返回操作系统,并提供一个返回代码(0)
  • 源程序汇编结束

    源程序的最后需要有一条汇编结束 END语句,这之后的语句不会被汇编程序所汇编。所以,汇编结束表示汇编程序到此结束将源程序翻译成目标模块代码的过程,而不是指程序终止执行END伪指令后面可以有一个“标号“性质的参数,用千指定程序开始执行于该标号所指示的指令

    • 使用END伪指令语句(不具备返回操作系统的功能)

四、第一个程序:信息显示

(1)输入输出子程序库

汇编语言作为低级程序设计语言 ,汇编程序通常并没有为其提供任何函数或程序库,所以必须利用操作系统的编程资源,课程书提供了简单易用的输入输出子程序库,实现了主要的键盘输人和显示器输出功能

  • 源程序文件开始使用包含命令声明

    • INCLUDE IO32.INC
  • 子程序调用方法

    • MOV EAX,入口参数
    • CALL 子程序名

(2)信息显示的汇编语言源程序

 ;eg0101.asm
        include io32.inc
        .data                         ;数据段
msg byte 'Hello, Assembly!',13,10,0
        .code                         ;代码段
start:                                ;程序执行起始位置
        mov eax,offset msg            ;指定字符串的偏移地址
        call dispmsg                  ;调用I/O子程序显示信息
        
        exit 0                        ;程序正常执行终止
        end start                     ;汇编结束

(3)常用输出子程序

C语言格式符 子程序名 功能说明
printf("%s",a) DISPMSG 显示字符串(以0结尾)
printf("%c",a) DISPC 显示一个字符
printf("\n") DISPCRLF 光标回车换行,到下行首列
DISPRD 显示8个32位通用寄存器内容
DISPRF 显示6个状态标志的状态
printf("%X",a) DISPHD 以十六进制形式显示8位数据
printf("%u",a) DISPUID 显示无符号十进制整数
printf("%d",a) DISPSID 显示有符号十进制整数

(4)常用输入子程序

C语言格式符 子程序名 功能说明
scanf("%s",&a) READMSG 输入一个字符串(回车结束)
scanf("%c",&a) READC 输入一个字符(回显)
scanf("%X",&a) READHD 输入8位十六进制数据
scanf("%u",&a) READUID 输入无符号十进制整数 ( ≤ 2 32 - 1 ) (≤2^{32}-1) (2321)
scanf("%d",&a) READSID 输入有符号十进制整数 ( - 2 31 ~ 2 31 - 1 ) (-2^{31}~2^{31}-1) (2312311)

你可能感兴趣的:(学习笔记,#,汇编语言,汇编语言)