美文网首页我爱编程
汇编语言--变量及数值操作

汇编语言--变量及数值操作

作者: william_zheng | 来源:发表于2018-05-27 10:38 被阅读0次

在高级语言中,变量和数值操作是很基本的语法,基本所有语言都有,但是其在汇编级别上是怎么实现的?或者拓展了说,在计算机上,变量和数值操作的实现逻辑是怎样的?

主要内容

  • 汇编与机器码
    首先,我们要知道,在计算机架构中,最重要的两层抽象是指令集和虚拟内存。前者是所有计算机程序的最小逻辑单元,即所有的计算机程序,都会被转换为一连串的计算机指令并运行。而虚拟内存则是计算机对程序可访问内存的一层抽象,因为这层抽象存在,每一个运行在计算机上的程序可以认为内存是一个只有自己和OS在使用超级大的字节数据。

    而计算机上存储、使用的数据都是二进制数(机器码)的形式,因此,所有的计算机指令都会被转换为对应的二进制数,计算机最终会根据这些不同的二进制数执行相应的计算机指令。但是二进制数是机器的语言,如果我们要直接使用二进制数进行编程,先不提各个机器上的相同指令对应机器码之间的差异性和代码的可读性问题,记忆各个指令对应的二进制数无疑是困难的。而如果我们设计一种人类可以很容易理解、记忆的语言,它与计算机指令有一一对应的关系,而我们只要再创建一个计算机指令编译器,将这种新语言转换对应的机器码,即解决了上述提到的各个问题。

    而汇编语言就是上面说的“新语言”,它只是对各个计算机指令二进制数的简单字符抽象,汇编语言的格式与编译器最终转换为的二进制数形式数据并没太大区别。下面是一个简单的代码实例:
    【待补充】

  • 数据类型
    在计算机上没有常规意义的数据类型的概念,即没有Integer,String类型之分。在 汇编语言中,只存在不同长度的二进制数,但是使用二进制数时,指令参数只有以下三种:

    1. 标量,例如$1$22,当它出现在指令参数时,参数的值就是其对应的二进制数,$符号只是在汇编的写法习惯,在实际的二进制代码中并不存在$前缀。
    2. 寄存器,例如%rax%rsi,当它出现在指令参数时,表示的值为存储在寄存器中的二进制数。和上面的标量表示一样,汇编的写法上一般会在寄存器名前加上%做为标识。使用寄存器作为参数时,需要注意,当指令要操作不同长度的二进制数时,我们要使用对应长度的寄存器名。例如,寄存器%rax的64位、32位、16位和8位的名称分别为%rax%eax%ax%al,那么当计算机指令操作16位数据时,需要用%ax标识该寄存器,8位则使用%al,需要与指令类型严格一致。
    图片来自《深入理解计算机系统》
    1. 内存数据,例如0x100(%rdi),当指令参数没有$|%前缀时,那么他就表示的是存放在内存某个位置的二进制数。这个时候,该二进制数的长度只取决于指令类型。 ()表示的是一种特殊的内存地址计算规则,计算规则为: 汇编语言内存计算.PNG 例如,100(, %rdi, 2),其中%rdi的值为0x1,则最终结果为100 + 1 * 2 = 102,即内存地址为102。
  • 访问数据(未完)

  • 算术逻辑操作

思考:

  • 在汇编语言中,如何表示高级语言中的变量?
    在高级语言中,变量往往就代表着程序的操作对象,可以作为计算结果的存储地点、程序的操作对象,甚至可以表示一段程序的执行过程。但是对于汇编语言来说,不管是可操作的数据,还是计算机指令本身,都只是一连串的二进制数,这些二进制数的具体含义,仅依赖于其在汇编程序中的上下文(指令类型及参数位置)。
    但是在汇编语言中并不存在变量的概念,汇编语言的操作对象是各个寄存器和内存数据,那么汇编语言是怎么表示高级语言中变量的语义的呢?
    我们先看一段代码,对于C语言函数:
    void concat_char(char a, char b, char *dest){
      dest[0] = a;
      dest[1] = b;
    }
    
    其转换的汇编语言可能是这样的:
    concat_char:
      movb  %dil, (%rdx)          %dil表示第一个参数所在的寄存器,%rdx表示第三个参数所在寄存器地址,由于第三个参数是指针,因此需要加上()表示取其指向的内存地址
      movb  %sil, (%rdx, $1, 1)   %sil表示第二个参数所在的寄存器,$1表示标量,即$1就表示了数值1,(%rdx, $1, 1)的语义为(%rdx + 1 * 1)指向的内存地址
      ret                         表示函数结束
    
    上面的汇编代码中,movb表示移动一个字节,参数有两个,第一个参数为源地址,第二个参数为目标地址。从上面汇编代码可以看出,对于汇编语言,不同的参数类型只代表着不同的数据大小。
    即使考虑更复杂的变量类型 ---- JAVA中的对象,其存储于计算机中也只是一连串的二进制数据,对于汇编语言来说也只有使用上的区别,即JVM转换为机器码时,可能会以不同的指令(同一类型指令,但是操作不同大小的数据)去操作对应对象数据的各个一部分(对应着对象实例的不同的字段类型),但是变量本身却只对应着某个寄存器或某个内存地址。
    总的来说,我们或许可以这样认为,在汇编语言并不存在变量的概念,但是我们可以通过操作不同数据大小的不同指令,结合寄存器和内存地址来模拟实现变量的效果。

相关文章

  • 汇编语言--变量及数值操作

    在高级语言中,变量和数值操作是很基本的语法,基本所有语言都有,但是其在汇编级别上是怎么实现的?或者拓展了说,在计算...

  • GCC数值原子操作API原理及应用

    文章来自GCC数值原子操作API原理及应用 一.前言 C/C++中数值操作,如自加(n++)自减(n–-)及赋值(...

  • 数值及日期操作

    数值操作 数值类型 1、NUMBER (P)表示整数 完整语法:NUMBER(precision,scale)如果...

  • 【python基础】2-数值和字符串数据类型

    数值 字符串 常量 内置操作符 Python会自动确定变量数据类型。变量在其他地方使用之前仅需要赋值。 数值 整数...

  • Python基础教程2-基础语法

    本期视频内容主要包括:数值计算、定义变量、字符串操作、列表、字典、元组基本操作、循环操作、定义函数基本操作本期代码...

  • Chapter 18 Runtime Environment

    C语言转化为汇编语言 1. 初始化static变量 2. 函数 函数部分分成三层: 前置操作,内容主题和清理操作。...

  • lupengday01

    变量及类型 列表 基本操作1 基本操作2

  • 从汇编来看 C 语言之变量

    汇编语言(机器语言)中没有变量的概念,一切操作都是直接对地址进行。 前置知识 例子: 在 printf("a = ...

  • spss学习4--重新编码

    1.概念: 对于不等距分组的操作,重新编码为不同的变量,重新编码可以把一个变量的数值按照指定的要求赋予新的数值,也...

  • js学习

    变量的声明 赋值 isNaN(n) 数值转换 parseInt 转换字符串 bool转换 比较操作符 三元操作符 ...

网友评论

    本文标题:汇编语言--变量及数值操作

    本文链接:https://www.haomeiwen.com/subject/jepmjftx.html