初识x86_64汇编-基础知识

小微 科技初识x86_64汇编-基础知识已关闭评论133字数 3288阅读模式
摘要上篇文章我们初步认识了nasm汇编器,使用一个&34;的程序描述编译运行的过程,需要注意的是我在此处描述不会以学术的方式做严格的定义,我的本意利用简单的白话描述,尽可能让每...

上篇文章咱们初步认识了nasm汇编器,使用一个&34;的程序描写编译运行的进程,需要注意的是我在此处描写不会以学术的方式做严格的定义,我的本意应用简单的白话描写,尽量让每一人都能简单理解这些概念以及实现。

术语以及概念

第一篇文章从整体上讲述了一个汇编程序运行的进程,这里面包括了大量的知识,不了解这些知识多是浏览者有些茫然,咱们在这里扼要的描写文章中触及的术语以及概念。文章源自微观生活(93wg.com)微观生活-https://93wg.com/4354.html

存放器

存放器是处理器内部的存储单元,处理器加载内存单元的数据通常很慢,处理器在其内部树立一个一个叫存放器的内部处理单元,加速CPU的执行效力,通常内存单元都需要加载到存放器中处理。文章源自微观生活(93wg.com)微观生活-https://93wg.com/4354.html

小端&大端

处理器以存储内存单元不同的布局区别大端以及小端序。通常咱们可以将内存想象为一个巨大的数组,这个数据存储了数据,索引叫做地址,这个数据每一一个单元存储了一个字节。文章源自微观生活(93wg.com)微观生活-https://93wg.com/4354.html

小端序文章源自微观生活(93wg.com)微观生活-https://93wg.com/4354.html

在小端序中存储数据是依照从大到小的存储方式寄存,也就是说位于高位的寄存在高地址内存单元,位于低位的寄存在低地址内存单元。文章源自微观生活(93wg.com)微观生活-https://93wg.com/4354.html

比如举个例子,在存储AA 56 AB FF4个字节的数据,在内存中表现为:文章源自微观生活(93wg.com)微观生活-https://93wg.com/4354.html

0 FF
1 AB
2 56
3 AA

第一列是内存单元,第二列是寄存的数据,高字节AA寄存在内存地址为3的地址上。Intel采取的存储是小端序。文章源自微观生活(93wg.com)微观生活-https://93wg.com/4354.html

大端序文章源自微观生活(93wg.com)微观生活-https://93wg.com/4354.html

以及小端序相反,高位的数据寄存在高地址,低位的数据寄存在低地址。在存储AA 56 AB FF4个字节的数据,在内存中表现为:文章源自微观生活(93wg.com)微观生活-https://93wg.com/4354.html

0 AA
1 56
2 AB
3 FF

大端序更为相符人类的浏览方式。文章源自微观生活(93wg.com)微观生活-https://93wg.com/4354.html

系统调用

系统调用是操作系统为用户程序提供的一组系统API,这些API屏蔽了底层硬件以及实现的繁杂性。而操作系统通常就是应用这些API提供了高层次的抽象,你可以在系统调用
中找到所有的系统调用。

咱们大部份的利用程序都是由栈来实现的,尤其是过程以及线程的模型,参数传递等功能都是应用其实现。

这个以及咱们程序中定义的栈抽象结构不是一回事情,但从本色上都是一个先进后出的队列。底层硬件为栈结构提供了很大的支持以及优化,RSP,SS,RIP。咱们后面会详细描写这个结构。

每一一个汇编程序通常都是有多个节组成,最多见的节有:

  • data 已经被初始化的变量以及常量通常存在这里
  • bss 没有被初始化的常量寄存在这里
  • text 指令代码寄存之处

通用存放器

在X86_64中由16个通用存放器rax, rbx, rcx, rdx, rbp, rsp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15。

这里不可能描写所有的术语以及概念,咱们会跟着进一步的加深,来描写遇到的概念以及专业术语。

数据类型

在汇编语言中,有字节,字,双字doublewords,4个字节),四字以及8字。

咱们这里描写的都是整数类型,通常有两个整数类型:

  • 无符号
    无符号类型的数据少了一个位表示符号位类型规模字节0 to 字0 to 双字0 to 4字0 to
  • 有符号
    有符号的使用一名表示符号位,唆使正负类型规模字节-2^7 to 字-2^5 to 双字–2^31 to 4字-2^63 to

就像咱们前面所说的,一个汇编程序有多个节组成,它可以表示初始化的数据节,代码节以及未初始化的节。一个节通常表示了一段连续的内存单元,由编译器进行分配。

例如,咱们声明初始化的数据:

section .data
num1: equ 100
num2: equ 50
msg: db &34;, 10

很显明,这段程序声明了3个变量num1,num2以及msg,它们的值分别是100,50以及&34;。或许您会问msg的变量为何以及其他不同样,这是由于在NASM中支撑一些伪指令,它们可以帮助简化咱们的开发。在NASM中:

  • DB, DW, DD, DQ, DT, DO, DY 以及 DZ - 用于声明初始化数据,例如

;; Initialize 4 bytes 1h, 2h, 3h, 4h
db 0x01,0x02,0x03,0x04

;; Initialize word to 0x12 0x34
dw 0x1234

  • RESB, RESW, RESD, RESQ, REST, RESO, RESY 以及 RESZ - 用于声明未初始化的数据
  • INCBIN - 引用外部二进制文件
  • EQU - 定义常量,例如:

;; now one is 1
one equ 1

  • TIMES - 重复执行指令以及数据

算术操作

下面列出了部份算术操作指令:

助记符

描写

ADD

SUB

MUL

无符号乘

IMUL

有符号乘

DIV

无符号除了

IDIV

有符号除了

INC

自增

DEC

自减

NEG

取负

有些指令您会在这章看到,有些会在后续的章节里面描写到。

节制流

通常咱们在高档语言中会看到扭转指令执行的顺序,同理在汇编语言中也有。咱们下面将重点描写汇编语言的节制流。

cmp指令执行两个操作数比较,cmp的功能至关于减法指令,只是对操作数之间运算比较,不保留结果。cmp指令执行后,将对标志存放器发生影响。例如:

;; compare rax with 50
cmp rax, 50

cmp指令将rax存放器中的内容同当即操作数50比较,在比较的进程中,cmp其实不影响操作数,它将会将比较结果影响标志存放器。通过前提转移指令,咱们就能够到达指令跳转的目的,咱们可使用下列前提挑战指令:

助记符

描写

JE

如果相等

JZ

如果为0

JNE

如果结果不相等

JNZ

如果结果不为0

JG

如果第一个操作数大于第二个

JGE

如果第一个操作数大于等于第二个

JA

以及JG同样,区分是做无符号比较

JAE

以及JGE同样,区分是做无符号比较

如果咱们但愿编写一个相似C语言中if/else的语句:

if {
exit;
} else {
right;
}

那么咱们可以这样写:

;; compare rax with 50
cmp rax, 50
;; perform .exit if rax is not equal 50
jne .exit
jmp .right

这里使用了无前提转移指令,语法如下:

JMP label

例如:

_start:
;; ....
;; do something and jump to .exit label
;; ....
jmp .exit

.exit:
mov rax, 60
mov rdi, 0
syscall

这里咱们可以在**_start**标签后面添加一些指令,这样这些指令被执行完后,程序会直接跳转到.exit执行退出程序。

这段程序GCC默许插入到咱们编写的C代码中,这样咱们就不需要显示的调用exit系统调用了,编译器自动添加退出程序。

无前提调转指令通经常使用在循环中。例如,咱们有一个标签,在这个标签后有一些执行代码,如果前提不知足,咱们可以跳转到标签处执行,直到前提知足。后面会有循环的案例代码。

**注意:**一般是了机能的斟酌,编译器会做一些优化,尽可能使用前提转送指令。

例子

咱们以一个例子收场本章,咱们使用两个整数,将两个数相加,然后同指定的数进行比较,如果指定的数等于两个数的以及,那么打印一些数据,否则,退出程序。

section .data
; Define constants
num1: equ 100
num2: equ 50
; initialize message
msg: db &34;

section .text

global _start

;; entry point
_start:
; set num1&39;s value to rbx
mov rbx, num2
; get sum of rax and rbx, and store it&34;Sum is correct\\n"。

  • 然后,指定程序启动执行点,在 _start标签。
  • 将两个常量num1以及num2使用数据转移指令分别放入通用存放器rax以及rbx
  • 执行sum指令,将结果寄存到rax存放器中
  • 得到了两个常量的以及后,使用cmp指令将rax存放器以及当即操作数150比较,因为这里num1以及num2分别为100以及50,所以rax的值为150,所以结果相等
  • 执行 rightSum标签后的内容,以及上一节同样打印数据到节制台
  • 执行完打印后,执行 .exit标签后的指令正常退出程序。
  • 总结

    咱们在这个章节中更为详细地了解了汇编程序中一个概念以及术语帮助咱们后面课程的学习。以一个例子收场了本章,对上一章的知识有一个更为深入的认识以及了解。

    以上就是微观生活(93wg.com)关于“初识x86_64汇编-基础知识”的详细内容,希望对大家有所帮助!

    继续阅读
     
    小微
    • 版权声明: 本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们(管理员邮箱:81118366@qq.com),情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!
    • 转载请务必保留本文链接:https://93wg.com/4354.html