计算机系统:硬件 + 软件ubuntu
#
开头的命令修改原始 C 程序,如:将incude
文件的内容插入到程序文本中。对于跨越多字节的程序对象,咱们须要确认:缓存
例如,变量x
类型为int
,值为0x01234567
,位于地址0x100
处,大端法和小端法存储为:sass
大端法:网络
地址 | 0x100 | 0x101 | 0x102 | 0x103 |
---|---|---|---|---|
数据 | 01 | 23 | 45 | 67 |
小端法:并发
地址 | 0x100 | 0x101 | 0x102 | 0x103 |
---|---|---|---|---|
数据 | 67 | 45 | 23 | 01 |
整数运算:<Z , +, x, -, 0 ,1>
(0, 1 为加法和乘法的单位元)函数
布尔代数:<{0, 1}, |, &, ~, 0, 1>
编码
上面两种结构有不少类似性,但注意~ a 不是 a 在 | 运算下的逆元(a | ~a != 0
, a + -a == 0
)操作系统
PS:线程
浮点数及其运算的标准:IEEE(读做 I-Triple-E) 标准 754翻译
符号 | 指数 | 有效数 | |
---|---|---|---|
单精度(32bit) | 1 | 8 | 23 |
双精度(64bit) | 1 | 11 | 52 |
指数采用二进制移码(Exponent bias)表示。
1 - Bias
(Bias 是指数域对应了二进制原码值)// code.c int accum = 0; int sum(int x,int y){ int t = x + y; accum += t; return t; }
生成汇编文件:$ gcc -O2 -S code.c
编译:$ gcc -O2 -c code.c
反编译:$ objdump -d code.o
,结果入下
ubuntu@DESKTOP-5JD9B9T:~$ objdump -d code.o code.o: 文件格式 elf64-x86-64 Disassembly of section .text: 0000000000000000 <sum>: 0: 8d 04 37 lea (%rdi,%rsi,1),%eax 3: 01 05 00 00 00 00 add %eax,0x0(%rip) # 9 <sum+0x9> 9: c3 retq
寻址的通用形式Imm(Eb, Ei, s)
,其地址是Memory[Immediate + Register[Eb] + Register[Ei] * scale]
(当即数 + 基址 + 变址)
mov S, D
:S ---> D
加载有效地址(Load Effective Address)指令 leal 其实是 movl 指令的变形。
这条指令将第一个操做数计算出的地址写入第二个操做数。
例如:leal 7(%edx, %edx, 4), %eax
将设置%eax
的值为7 + %edx + 4 * %edx
。(%edx
为 3,则%eax
设置为 22)
一元操做:只有一个操做数,既是源又是目的。
二元操做:第二个操做数既是源又是目的。
跳转(jump)指令会致使执行切换到程序中的一个全新的位置。这些跳转的目的地一般用一个标号(label)指明。
执行 PC 相关寻址时,程序计数器的值是跳转指令后面的那条指令的值,而不是跳转指令自己的地址。处理器会将更新程序计数器做为执行一条指令的第一步。例如:
地址 指令1 0x08 指令2 0x0a ... 指令n 0x1b 若是指令1的操做是跳转到指令n,则偏移为0x11,由于0x0a + 0x11 = 0x1b