IA32和X86有什么区别?

简介: IA32和X86有什么区别?

1.数据传送指令


格式:MOVX source, destination

X: L 32位值 W 16位值 B 8字节

MOVL %EAX, %EBX

MOVW %AX, %BX

MOVB %AL, %BL

使用规则,mov只有以下13种情况


情况    举例

立即数==>通用寄存器    movl $0, %eax

立即数==>内存位置    movl $100, value

通用寄存器==>通用寄存器    movb $al, %cl

通用寄存器==>段寄存器    movl %edx, %cs

通用寄存器==>控制寄存器    movl %edi, %cr0

通用寄存器==>调试寄存器    movl

段寄存器 ==>通用寄存器    movl %ds, %esi

控制寄存器==>通用寄存器    movl %cr4, %esp

调试寄存器==>通用寄存器    

内存位置==>通用寄存器    movl value, %eax

内存位置==>段寄存器    

通用寄存器==>内存位置    movl %ecx, value

段寄存器 ==>内存位置    

变址寻址


地址格式: base_addr(offset_addr, index, size)

数据值位于base_addr + offset_addr + index * size

offset_addr,index必须为寄存器值,size可以是数字值

movl $2, %edi
movl values(, %edi, 4), %eax


寄存器间接寻址


$加标签获取内存位置的地址


movl $values, %edi ;把values地址送进EDI
movl %ebx, (%edi)  ;把EDX值送到EDI中包含的内存位置处
movl %ebx, 4(%edi) ;把值放到EDI寄存器指向位置之后4个字节的内存位置处
movl %ebx, -4(%edi);把值放到EDI寄存器指向位置之前4个字节的内存位置处


2. 条件传送指令


条件传送指令可以避免处理器执行JMP指令,这有助于处理器的预取缓存状态,通常能提高应用程序的速度


指令格式 : CMOVX source, destination

X是1个或2个字母的代码,表示将触发传送操作的条件;

条件取决于EFLAGS寄存器当前值 使用的位


交换数据


XCHG OP1, OP2

op1和op2可以同时为通用寄存器或者一个是内存位置(不能同时为内存位置)

8 bit, 16 bit, 32 bit寄存器都可以使用

当其中一个操作数是内存位置时,处理器LOCK信号自动标明,防止交换过程中其他处理器访问这个内存位置。

LOCK是非常耗时间的,并且可能对程序性能有不良影响。


BSWAP REG

反转寄存器字节顺序,大端变小端


XADD SOURCE, DESTINATION

交换两个寄存器的值或寄存器和内存位置的值,然后相加存到destination中


CMPXCHG SOURCE, DESTINATION

如果destination和EAX/AX/AL相等,把source加载到destination;

否则,把destination加载到EAX/AX/AL中


CMPXCHG8B DESTINATION

如果destination处8字节和EDX:EAX包含值匹配,ECX:EBX中64位值加载到destination内存位置;

否则destination内存位置值加载到EDX:EAX中。


压栈 pushx source


X:l用于长字32bit,w用于半字16bit

操作数是

16bit/32bit 立即数值

16bit/32bit 内存值

16bit/32bit 寄存器值

16bit 段寄存器

e.g.


pushl   %ecx
pushw  %cx
pushl  $100
pushl   data  ;push data值
    pushl   $data ;push data的地址


出栈 popx destination


16bit/32bit 寄存器

16bit 段寄存器

16bit/32bit 内存位置

e.g.

popl   %ecx
popw  %cx
popl   value

ESP寄存器是堆栈指针跟踪着堆栈的开始位置


压入和弹出所有寄存器



PUSHA 压入16位寄存器 顺序DI, SI, BP, BX, DX, CX, AX

PUSHAD压入32位寄存器 顺序EDI, ESI, EBP, EBX, EDX, ECX, EAX


手动使用ESP,EBP手工把数据放入堆栈

通常 很多程序把ESP值复制到EBP,而不是使用ESP本身


优化内存访问:奔腾四的处理器中,缓存块长度是64bit,定义的数据超过64位,就需要两次访存操作。


5 控制执行流程


无条件分支 : 跳转;调用;中断


跳转


汇编程序不认为跳转是不良的程序设计,对程序的性能有影响

jmp location location是要跳转到的内存地址,被声明为代码中的标签;

遇到跳转时指令指针改编为紧跟在标签后面的指令码的内存地址。


调用


保存发生跳转的位置,并且具有在需要时返回这个值的能力

call address:引用程序中的标签,他被转换为函数中的第一条指令的地址

返回指令RET没有操作数,通过查看堆栈,它知道返回什么位置



函数调用模板

Function_label:
Pushl %ebp
Movl %esp, %ebp
<normal code>
Movl %ebp, %esp
Popl %ebp
Ret


e.g.

;calltest.s
;An example of using the CALL instruction
.section .data
output:
   .asciz "This is section %d\n"
.section .text
.globl _start
_start:
   pushl $1
   pushl $output
   call printf
   add  $8, %esp
   call overhere
   pushl $3
   pushl $output
   call printf
   add  $8, %esp
   pushl $0
   call exit
overhere:
   pushl %ebp
   movl %esp, %ebp
   pushl $2
   pushl $output
   call printf
   add  $8, %esp
   movl %ebp, %esp
   popl %ebp
   ret


x86


早期,1980s年代,x86一般指当时的处理器8088和80286,不过这两个处理器都是16位的。如今,x86通常指32位指令集架构的处理器,比如80386。80386处理器是intel在1985年实现的第一款32位指令集架构的处理器,又叫i386,Intel Architecture, 32-bit,缩写为IA-32,现在,IA-32一般又能引喻成所有的支持32位计算的x86架构。


按照发展历史看,x86应该是指令集概念,一般用于个人PC系统如8086,286,386。IA-32是intel首推的32位架构。


x86-64/x64/amd64/Intel64


在1999年,AMD公司首先在IA-32基础上,增加了64位寄存器,兼容早期的16位和32位软件系统,推出了x86-64的64位微处理器,后来命名为AMD64,实现了超车。然后intel公司也接受了该方案,叫做Intel64。x86-64应该只算是x86指令集的64位扩展,并不是一种全新的64位架构。


由于amd64和intel64本质上是一样的,叫法也是很多。AMD通常叫它x86-64、x86_64,微软和sun等软件公司叫它x64,操作系统厂商则通常用AMD64或者amd64来指代AMD64和Intel64。


IA-64


IA-64是Intel推出的用于Itanium处理器(安腾处理器)的自己的Intel Architecture 64位指令集,一般用于服务器。尽管Intel64也是64位处理器,但这两者完全不是一回事。IA-64软件不能直接运行于Intel64处理器上。x86-64是IA-32指令集的扩展,而IA-64则是完完全全没有一点IA-32影子的独立处理器架构。IA-64需要通过模拟器才能运行IA-32,但是性能大大受影响。


市面上处理器如何区分AMD64和IA-64呢?


市面上买的Intel 64-bit的cpu其实都属于amd64分类,intel64和amd64其实都应该叫做x86_64。

IA64则指Itaniums系统cpu,并不是x86架构的,一般都是用于服务器,不是个人桌面产品,价格昂贵。

ARM64/AArch64


ARM是精简指令集RISC下的处理器架构。ARMv3至ARMv7支持32位寻址空间。ARMv8-A开始支持64位寻址空间。AArch64和ARM64都是指64位的ARM架构。


[参考]:


https://en.wikipedia.org/wiki/AArch64

https://en.wikipedia.org/wiki/IA-32

https://titanwolf.org/Network/Articles/Article?AID=f0882831-3c86-4201-9418-da3a05626bed#gsc.tab=0

https://en.wikipedia.org/wiki/X86


相关文章
|
6月前
|
机器学习/深度学习 分布式计算 C语言
Julia
Julia
61 0
|
5月前
|
存储
Julia 数据类型
Julia中的数据类型包括整数和浮点数,以及字面量。类型转换通过T(x)、convert(T,x)或x % T实现,其中错误转换会抛出InexactError。示例展示了Int8类型的转换,如成功转换127,但128会引发错误。舍入函数如round(Int8, x)简化了转换,但同样可能因不精确而报错。
|
2月前
|
分布式计算 并行计算 Unix
Julia 教程
Julia 是一个开源的编程语言,采用 MIT 许可证,每个人都可以免费使用。
40 8
|
6月前
|
存储 索引
Julia 数组
Julia的数组是可变的、类型可异的顺序集合,支持一维和多维。索引使用整数,大小不固定。通过方括号创建,元素间用逗号分隔。例如,`[1,2,3]`创建一个整数向量,而`[1, &quot;baidu&quot;, 2.5, pi]`创建一个包含不同类型的数组。可以指定类型,如`Int64[1,2,3]`创建整数数组,`String[&quot;Taobao&quot;,&quot;baidu&quot;,&quot;GOOGLE&quot;]`创建字符串数组。Julia提供多种函数支持数组操作,如添加和合并元素。
|
5月前
|
Unix Windows Linux
Julia 语言环境安装
摘要:Julia 语言可在 Linux, FreeBSD, macOS, Windows 和 Android 上安装。下载地址:https://julialang.org/downloads/,源码:https://github.com/JuliaLang/julia。
|
6月前
|
索引
Julia 数组基本函数
摘要: 了解 Julia 中的数组基本函数:eltype() 获取元素类型,length() 返回元素数量,ndims() 给出维数,size() 和 size(A,n) 用于获取维度大小,axes() 和 axes(A,n) 提供索引范围,eachindex() 用于遍历,stride() 和 strides() 描述元素间隔。
Julia 元组
Julia 中的元组是不可变的有序元素集合,与数组用法相似但用小括号表示。创建元组如 `(5, 10, 15, 20, 25, 30)`,可以使用数组函数操作,如 `tupl[3:end]` 获取子元组。尝试修改元组元素会导致错误,如 `tupl2[2]=0` 会抛出 `MethodError`。
Julia 基本语法
Julia 的注释方式包括单行和多行。单行注释以 `#` 开始,如 `# 这是一行注释`。多行注释使用 `#=` 开始并以 `=#` 结束,示例:`#= 1、这是一行注释\n2、这是另外一行注释 =#`。`println(&quot;Hello World!&quot;)` 是打印语句。
|
数据可视化 API
Julia:Plots 包的属性汇总
这篇文章是 Julia 的 Plots 包的各种属性的汇总
170 0
Julia:Zygote 上自定义后向传播
Zygote 是 Julia 上一个实现自动微分、自动求导的包,其中 `@adjoint` 宏是 Zygote 接口的一个重要组成部分。使用 `@adjoint` 可以自定义函数的后向传播。
106 0