《汇编程序设计与计算机体系结构: 软件工程师教程》这本书是由Brain R.Hall和Kevin J.Slonka著,由爱飞翔译。中文版是2019年出版的。个人感觉这本书真不错,书中介绍了三种汇编器GAS、NASM、MASM异同,全部示例代码都放在了GitHub上,包括x86和x86_64,并且给出了较多的网络参考资料链接。这里只摘记了NASM和MASM,测试代码仅支持Windows和Linux的x86_64。

3. 汇编语言及其语法的基础知识

3.2 基本元素:

汇编代码的五大支柱:保留字(reserved word)、标识符(identifier)、命令(directive, 也称为指示或伪操作)、区段(section或segment, 简称段)以及指令(instruction)。

(1). 保留字:是一种具备特定用途的字词。例如MOV就是个保留字,它代表一条特定的指令,即MOV指令。你不能把它当成变量名来用,也不能做其它用途。汇编语言的保留字不区分大小写。指令(例如MOV)、命令(例如PROC)、寄存器(例如eax)、属性(例如可以当作.MODEL命令参数值的FLAT)等,都是保留字。

(2). 标识符:是由程序员所定义的名称,用来表示变量、常量及过程等事物,它最多可以包含247个字符。第一个字符不能是数字,且必须从英文字母(大写的A至Z及小写的a至z)、下划线(_)、问号(?)、at符号(@)及美元符号($)这五种中选择,其后的字符则可以使用数字

(3). 命令:是与指令集无关的一些操作,可以指挥汇编器去做某件事,例如定义变量、指明内存段等。

下表列出了32位程序MASM版本特有的命令:用MASM编写64位程序的时候不需要使用此表中的命令。

(4). 程序段(program section或program segment):是用相关命令所标出的特殊段落。汇编器预先定义了几种这样的段落。下表列出了撰写汇编代码时常有的几种程序段:

(5). 指令:是程序中的可执行语句。指令由两个基本部分组成,其语法如下:”mnemonic  [operands]”,其中mnemonic(助记符)是指令的名称,开发者用它来指代某个架构所支持的一套指令集里的一条指令。助记符通常是个缩写形式或首字母缩略形式的词,实际上也可以认为是数字形式的操作码所对应的英语写法。有些指令不需要操作数,有些则需要一个、两个或三个操作数。

字面量(literal value, 字面值):也叫做立即值(immediate, 立即数),用来表示那些由开发者明确指定的值,例如整数、实数、字符、字符串等。

整数字面量(integer literal):一般写为十进制(或者说以10为底的进制)的整数。在有些情况下也可以(甚至是必须)采用其它进制来写。MASM及NASM允许开发者在字面量之后写上一个表示基数的字符,以指出这个字面量所采用的进制。如二进制b、十进制d、十六进制h、八进制o或q。有一种情况要注意,十六进制数的数位中可能会出现A至F这几种英文字符。如果某个十六进制数(例如内存地址)是以英文字符开头的,那么汇编器就会把它当成标识符看待,为了令其能够正确地将该值解读为字面量,你应该在前面添一个0.

字符字面量(character literal):是由单个字符所构成的值,与整数字面量一样,也用来表示那种开发者在编写程序代码的时候就已经很清楚的值。MASM与NASM中的字符字面量可以用一对单引号括起来,也可以用一对双引号括起来,这两种写法是等效的。字符在存储器中是以整数形式的ASCII编码来表示的。

字符串字面量(string literal):是由多个字符字面量所组成的,通常用来表示单词或短语。MASM与NASM的字符串与单个字符类似,也可以用一对单引号或双引号括起来。如果字符串的内容本身就有引号,那么对于MASM及NASM来说,你必须用另外一种引号把这个字符串括起来。字符串通常保存成字节数组,其中的每个字节都与字符串中处在该位置上的字符相对应,字节的内容就是字符的ASCII码。

标签(label):可以用来划分代码,以表达某种与编程或设计有关的想法。它不仅可以令代码读起来更加清晰,而且有的时候还能够帮助开发者实现跳转或循环等功能,使得程序可以跳到标签所标识的这个地方。标签的写法是在标识符后面跟一个冒号。标签可以单独占据一行也可以与指令写在同一行。NASM的标签用在.text段里    的标签区分大小写,MASM的标签写在.code段里则不区分大小写

汇编语言的注释可以分成两种:单行注释与多行注释。MASM及NASM的单行注释以分号(;)开头。注释可以单独占据一行也可以写在某行代码的后面。多行注释只能在MASM中用。MASM的多行注释必须与其它代码分别写在不同的行里,而且要由四部分组成:COMMENT、起始字符、注释文本、终止字符。起始字符与终止字符必须采用同一种字符,而且要注意不能与注释文本中的任何一个字符相同(否则注释就会提前结束)。MASM的多行注释习惯上采用感叹号(!)作为起、止字符。

3.3 定义数据:

汇编语言的数据类型根据数据的大小来确定(例如8位、16位、32位)。下表列出了各种汇编器所支持的数据类型:无论采用哪种汇编器,.data段里定义的变量都必须予以初始化,也就是必须具备初始值

变量采用下列语法来定义:

NASM:[标识符:] 命令 初始化器 [, 初始化器] …

MASM:[标识符] 命令 初始化器 [, 初始化器] …

一个标识符后面带有多个初始化器的写法可以用来创建数组(array),也就是创建一系列大小相同的值。这些值都可以通过数组的名称加以引用,该名称本身指的是序列中的第一个值(或序列中的第一个值在内存中的位置)。充当数组名称的标识符其实是指向数组中首个值的引用,它表示的是该值在内存中的位置。

有的时候,程序中需要定义未初始化的变量。这种变量不具备初始值,它主要是为了在内存中预留一定的空间以供开发者使用。对于这种变量,不同的汇编器所采用的定义方式之间有很大的区别。NASM要求.data段里的变量必须用明确的值来初始化,而MASM则允许开发者在该段中采用问号(?)充当变量的初始化器来定义未初始化的变量

MASM的初始化器可以用DUP括起来,以便反复创建大小与内容均相同的多个值。凡是有效的初始化器都可以用DUP命令加以重复,这也包括问号。

NASM要求未初始化的变量必须创建在.bss段中(bss的意思是Block Started by Symbol,以符号开始的块),而且要用特定的命令来创建,如下表所示:能够通过相应的命令,以单个变量或数组的形式来预留各种数据类型的未初始化空间。

字符串是以BYTE(字节)数组的方式存储的。字符串必须以null结尾,也就是说,其最后一个字节必须是值为0的ASCII码。不同的汇编器采用不同的方式来定义这种字符串。MASM与NASM则是直接用字面量0来设置最后一个字节。一个涉及字符串的重要问题是换行。不同的汇编器采用不同的方式换行。MASM用十六进制码0Dh与0Ah来表示CR/LF这两个符号并以此实现换行(CR的意思是carriage-return, 回车)。NASM则只用0Ah这一个十六进制码(也就是LF)表示换行

符号常量(symbolic constant)可以在MASM版本的汇编代码里取代某些变量,用以表示程序执行期间绝对不会变化的值。x86的符号常量能够表示32位整数,x86_64的符号常量能够表示64位整数,常量所表示的都是基于整数的数据。你可以用等号(=)定义这样的常量。MASM里的符号常量不占内存,因为MASM在对代码作汇编的时候,会把所有出现符号常量的地方都改成该常量所对应的实际值。采用等号来定义符号常量的写法只适用于MASM汇编器。此外,MASM的符号常量还可以用来表示字符串值。

所有的汇编器都可以把表达式的值表示成符号常量。符号必须用EQU命令来定义。与定义变量时的要求不同,用EQU所创建的符号既可以出现在数据段也可以出现在代码段(对于MASM汇编器,它可以出现在.data与.code段,对于NASM汇编器,它可以出现在SECTION .data与SECTION .text段)。这些汇编器在对代码作汇编的时候会把每一个出现这种符号的地方都替换成对应的表达式。建议只针对数值表达式来使用EQU命令。EQU命令还有一个用途,是通过创建符号常量来表示某个标识符所指代的数据占用了多大的内存空间。当前位置计数器(current location counter)用来指代位置计数器的当前内存地址(MASM及NASM用美元符号$表示),将该地址与前一个字符串的起始内存地址相减即可算出字符串所占据的字节数。MASM可以通过等号(=)把计算结果定义成标识符。

MASM还提供了一种写法,能够创建动态符号,称为文本宏(text macro)。由TEXTEQU命令所创建的符号可以表示涉及其它符号的表达式,甚至还可以表示指令。注意,由于指令不是整数表达式,因此它的左右两端是用尖括号括起来的。

Windows上使用VS编译MASM汇编操作步骤

(1). 创建一个Win32控制台应用程序AssemblyLanguage_Test;

(2). 右键单击该项目-->生成依赖项-->生成自定义:勾选masm复选框,点击确定;

(3). 添加一个新建文件funset.asm;

(4). 右击funset.asm-->属性:常规:项类型调整为:Microsoft Macro Assembler;

(5). 右键单击该项目-->属性:链接器:系统:子系统:调整为:窗口 (/SUBSYSTEM:WINDOWS);链接器:高级:入口点:填写为_main;

(6). 向funset.asm编写汇编代码,测试代码来自于:https://github.com/brianrhall/Assembly/blob/master/Chapter_3/Program%203.2/x86_64/Program_3.2_MASM.asm

可以在适当的位置设置断点,F5运行程序,打开寄存器、内存、反汇编、监视等窗口查看相关内容;可以在寄存器窗口中单击鼠标右键,选择”标志”查看标志寄存器的值,结果如下图所示:

Ubuntu上编译NASM汇编操作步骤

(1). 新建文件funset.asm,测试代码来自于:https://github.com/brianrhall/Assembly/blob/master/Chapter_3/Program%203.2/x86_64/Program_3.2_NASM.asm

(2). 脚本文件build.sh内容如下:

#! /bin/bashnasm -f elf64 -o funset.o funset.asm
ld -e _main -melf_x86_64 -o funset funset.o
#./funset

可以通过gdb查看寄存器、变量等相关值,结果如下图所示:

GitHub:https://github.com/fengbingchun/CUDA_Test

汇编程序设计与计算机体系结构软件工程师教程笔记:汇编语法基础知识相关推荐

  1. 汇编程序设计与计算机体系结构软件工程师教程笔记:内联汇编与宏

    <汇编程序设计与计算机体系结构: 软件工程师教程>这本书是由Brain R.Hall和Kevin J.Slonka著,由爱飞翔译.中文版是2019年出版的.个人感觉这本书真不错,书中介绍了 ...

  2. 汇编程序设计与计算机体系结构软件工程师教程笔记:函数、字符串、浮点运算

    <汇编程序设计与计算机体系结构: 软件工程师教程>这本书是由Brain R.Hall和Kevin J.Slonka著,由爱飞翔译.中文版是2019年出版的.个人感觉这本书真不错,书中介绍了 ...

  3. 汇编程序设计与计算机体系结构软件工程师教程笔记:指令

    <汇编程序设计与计算机体系结构: 软件工程师教程>这本书是由Brain R.Hall和Kevin J.Slonka著,由爱飞翔译.中文版是2019年出版的.个人感觉这本书真不错,书中介绍了 ...

  4. 汇编程序设计与计算机体系结构软件工程师教程笔记:处理器、寄存器简介

    <汇编程序设计与计算机体系结构: 软件工程师教程>这本书是由Brain R.Hall和Kevin J.Slonka著,由爱飞翔译.中文版是2019年出版的.个人感觉这本书真不错,书中介绍了 ...

  5. 汇编程序设计与计算机体系结构软件工程师教程笔记:总结

    <汇编程序设计与计算机体系结构: 软件工程师教程>这本书是由Brain R.Hall和Kevin J.Slonka著,由爱飞翔译.中文版是2019年出版的.个人感觉这本书真不错,书中介绍了 ...

  6. 计算机四级c语言题库及答案,2016计算机四级软件工程师考试题库及答案

    2016计算机四级软件工程师考试题库及答案 (B)软件故障是指软件代码中的错误 (C)在软件的一次运行期间,软件故障一定会导致软件失效 (D)通常修改软件故障可以降低软件发生失效的概率,从而提高软件可 ...

  7. Udacity机器人软件工程师课程笔记(五)-样本搜索和找回-基于漫游者号模拟器-自主驾驶

    9.自主驾驶 在接下来的环节中,我们要实现漫游者号的自动驾驶功能. 完成这个功能我们需要四个程序,第一个为感知程序,其对摄像头输入的图片进行变换处理和坐标变换使用.第二个程序为决策程序,功能是帮助漫游 ...

  8. 全国计算机等级考试二级c语言程序设计,全国计算机等级考试二级教程:C语言程序设计(2016年版) pdf epub mobi txt 下载...

    全国计算机等级考试二级教程:C语言程序设计(2016年版) pdf epub mobi txt 下载 图书介绍 ☆☆☆☆☆ 教育部考试中心 编 下载链接在页面底部 发表于2021-05-17 类似图书 ...

  9. 非核心版本的计算机上_计算机四级网络工程师知识点笔记(备考指南)

    计算机四级网络工程师是先要通过计算机三级网络技术. (计算机三级网络技术笔记翻公众号历史文章) 计算机四级是考两个科目 操作系统30个选择题10个多选题 计算机网络30个选择题10个多选题 两科各拿3 ...

最新文章

  1. 不懂 Zookeeper?没关系,看这篇就够了!
  2. CreateThread、_beginthreadex、AfxBeginThread
  3. php 输出rtf,有没有办法在PHP中访问压缩RTF和输出RTF代码
  4. Git设置忽略文件/文件夹
  5. python中迭代器和生成器的区别
  6. 安全问题汇总(一) 证书定期检查和及时更新
  7. 【转】Tomcat总体结构(Tomcat源代码阅读系列之二)
  8. Spring MVC 入门指南(二):@RequestMapping用法详解
  9. android 内存抖动_android内存泄漏怎么破?一招教你搞定!
  10. Java大厂面试100题,你面试时总会用到的!
  11. Spring Batch系列总括(转载)
  12. 省级面板数据(1990-2019):能源生产等(原油、石油、焦炭、原煤、天然气等)stata或excel版本
  13. 庞加莱买面包的故事(一)
  14. 家用千兆路由器排行榜前十名_家用路由器排名前十名
  15. JSP程序设计实训(十一)——JSP与Servlet技术(一)
  16. 黄子韬快手带货首秀GMV破2.3亿,真性情无套路直播效果拉满!
  17. 3分钟弄明白顶级域名二级域名子域名父域名的区别
  18. 安全加密与证书签发工具--openssl
  19. 2018 react 大会_2018年React.js全面指南
  20. SpringBoot后台java下载文件及注意的地方

热门文章

  1. Shell编程-用户信息管理
  2. 软件测试培训哪里好?就业前景可观吗?
  3. functools partial详解
  4. tengine简单安装_tengine快速安装
  5. 黑马学成在线项目之Day4实战
  6. 在京东如何做好前端系统的可观测性
  7. win7下使用隐藏的虚拟wifi共享上网
  8. osgearth自带工具介绍
  9. 关于如何卸载流氓软件 巧压--来自北京小树发芽科技网络有限公司
  10. 傍晚的夕阳映红了你的双颊