Skip to content

Latest commit

 

History

History
218 lines (181 loc) · 5.92 KB

ch07.md

File metadata and controls

218 lines (181 loc) · 5.92 KB

使用数字

表示数字和使用数字是汇编语言的重要部分

数字类型

核心的数字类型有几种

Unsigned integers
Signed integers
Binary-coded decimal
Packed binary-coded decimal
Single-precision floating-point
Double-precision floating-point
Double-extended floating-point

除了基础的数字类型,在奔腾处理器上SIMD extensions增加一些更高级的数字类型

64-bit packed integers
128-bit packed integers
128-bit packed single-precision floating-point
128-bit packed double-precision floating-point

整型

在汇编当中最基本的就是整型.

标准整型大小

Byte: 8 bits
Word: 16 bits
Doubleword: 32 bits
Quadword: 64 bits

理解存储在内存当中高于一个字节的整数,是按小端存储的。这代表着最低位的字节存储在最低位字节的内存位置,剩下的高位字节紧随其后. 但是当整型数据移动到寄存器的时候,是按大端存储的,这个时候就有些令人困惑了. 这种转化对于用户来说是透明的,所以也不需要特别的担心,但是当你调试程序的时候发现下面的情况,不要慌张.

(gdb) x/x &data
0x80490bc <data>:	0x00000225
(gdb) x/4b &data
0x80490bc <data>:	0x25	0x02	0x00	0x00
(gdb) print/x $rax
$1 = 0x225
(gdb)

//TODO:64位估计不是x/4b 猜是x/8b,以后再验证 十进制数549存储在内存的data处,然后移动到RAX寄存器.第一条gdb指令显示的是在data处十六进制的内容.第二条指令显示4个用来构成这个字节的内存,这就是小端的形式.

注意前方高能,需要脑补机组的知识

无符号整数

无符号整数就是一种你看到是多少就是多少的类型("what you see is what you get").构成数字的字节直接用来表示这个数. 相应无符号整数的范围


Bits	Integer Values
8	0 through 255
16	0 through 65,535
32	0 through 4,294,967,295
64	0 through 18,446,744,073,709,551,615

以后举例子几个类型内存的的表示,基本上大同小异.

有符号数

有三种方法表示符号数分别是

Signed magnitude
One’s complement
Two’s complement

Signed magnitude

有首位表示正负,但是会有+0和-0出现,而且不能通过直接加减得到对应的答案.

One's complement

传说中的反码表示,把对应位取反,比如00000001对应的是1111110,这样的方式还是有问题,具体以后解释.

Two's complement

传说中的补码表示,负数取反加1,正数不变就是补码.这样的好处是加减的时候得到的补码能够正确反应结果.

使用有符号数

# inttest.s - An example of using signed integers
.section .data
data:
.int -45
.section .text
.globl _start
_start:
nop
movl $-345, %ecx
movw $0xffb1, %dx
movl data, %ebx
mov  $60, %rax
syscall

//TODO:改成64位的寄存器 这些都是使用数字的方法,但是不同的是我们通过调试的时候会有如下情况

(gdb) info reg
eax	0x0	0
ecx	0xfffffea7	-345
edx	0xffb1	65457
ebx	0xffffffd3 -45

数字都是存对了,但是edx之所以是那个数是因为将edx整个看作一个数了,而不是取dx的那几位. 所以寄存器在分辨数字的时候也是挺令人困惑的.

扩展数字

有时候你需要将word大的数字放到doubleword大的地方,这看起来很容易,但实际上有点困难.

扩展无符号整数

向大尺寸移动的时候要确保高位都被设为0.例如movw %ax,%bx这个不能保证正确,你应该将高位清零.

movl $0, %ebx
movw %ax, %ebx

这样才能保证移动是正确的. 但是有一个MOVZX指令可以帮你完成这件事高位清零的事.当然使用的时候也要注意源寄存器的大小,以免没有完全复制.

扩展有符号整数

扩展有符号数又不简单了,因为有符号数的-1(11111111)如果要扩展到doubleword会变成000000001111111,这个数是127而不是-1了. 所以对于有符号数来说增加的位需要为1.

Intel提供了MOVSX指令允许有扩展有符号数并且保持符号不变。这有点像MOVZX但是假设操作数的是有符号的数. //TODO:补充一个例子

定义一个整数

在第五章当中提到的.int,.short,.long命令都是用来定义整型数字的.还可以用.quad来定义quadword有符号数. //TODO:这个似乎32和64有点区别,以后更

SIMD 寄存器

The Intel Single Instruction Mutiple Data技术能够提供额外的方法使用整型.//TODO:给个简单的解释

MMX 整型

The Multimedia Extension technology 提供3个整型类型:

64-bit packed byte integers
64-bit packed word integers
64-bit packed doubleword integers

每个MMX寄存器可以容纳多个整型元素,如图,补个图 //TODO:加个图

移动 MMX 整型

# mmxtest.s - An example of using the MMX data types
.section .data
values1:
.int 1, -1
values2:
.byte 0x10, 0x05, 0xff, 0x32, 0x47, 0xe4, 0x00, 0x01
.section .text
.globl _start
_start:
nop
movq values1, %mm0
movq values2, %mm1
mov $60,%rax
syscall

//TODO:说明

SSE 寄存器

The Streaming SIMD Extension(SSE)技术提供128bit的XMM寄存器.The SSE2 techonology(在奔腾4引入)提供额外的4个整数类型

128-bit packed byte integers
128-bit packed word integers
128-bit packed doubleword integers
128-bit packed quadword integers

//TODO:补充个图

移动 SSE 整型

依赖 MOVDQAMOVDQU 命令.//TODO:补充例子和解释

二进制编码十进制

The Binary Coded Decimal (BCD) 数据类型存在了很长的时间.

什么是BCD

//TODO:解释

FPU BCD 数值

BCD 使用FPU寄存器来存储 //TODO:解释

移动 BCD 数值

依赖fbld source命令,source是一个80bit内存的地址

#bcdtest.s - An example of using BCD integer values
.section .data
data1:
	.byte 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
data2:
	.int 2
.section .text
	.globl _start
_start:
	nop
	fbld data1
	fimul data2
	fbstp data1
	mov $60,%rax
	syscall

//TODO:解释

浮点数