深入理解计算机系统基础(三)

前言

这一章我们要学习汇编代码,不要求会由C写汇编,但简单的汇编代码要会读,应此,相应转换规则需要熟记

数据格式

C声明Intel数据类型汇编代码后缀大小(字节)
char字节b1
shortw2
int双字l4
long四字q8
char*四字q8
float单精度s4
double双精度l8

访问信息

操作数指示符

寄存器

在这里插入图片描述
前六个寄存器(%rax, %rbx, %rcx, %rdx, %rsi, %rdi)称为通用寄存器,有其『特定』的用途
%rax(%eax) 用于做累加
%rcx(%ecx) 用于计数
%rdx(%edx) 用于保存数据
%rbx(%ebx) 用于做内存查找的基础地址
%rsi(%esi) 用于保存源索引值
%rdi(%edi) 用于保存目标索引值

传送

对于 movq 指令来说,需要源操作数和目标操作数,源操作数可以是立即数、寄存器值或内存值的任意一种,但目标操作数只能是寄存器值或内存值。指令的具体格式可以这样写 movq [Imm|Reg|Mem], [Reg|Mem],第一个是源操作数,第二个是目标操作数,例如:

*movq Imm, Reg -> mov $0x5, %rax -> temp = 0x5;
movq Imm, Mem -> mov $0x5, (%rax) -> *p = 0x5;
movq Reg, Reg -> mov %rax, %rdx -> temp2 = temp1;
movq Reg, Mem -> mov %rax, (%rdx) -> *p = temp;
movq Mem, Reg -> mov (%rax), %rdx -> temp = p;

接下来看一个具体的例子:

long m12(long x)
{
    return x * 12;
}

其对应的汇编是:

leaq (%rdi, %rdi, 2), %rax # t <- x+x*2
salq $2, %rax              # return t << 2

FOR循环

long absdiff(long x, long y)
{
    long result;
    if (x > y)
        result = x-y;
    else
        result = y-x;
    return result;
}

对应的汇编结果:(其中 %rdi 中保存了参数 x,%rsi 中保存了参数 y,而 %rax 一般用来存储返回值)

absdiff:
    cmpq    %rsi, %rdi
    jle     .L4
    movq    %rdi, %rax
    subq    %rsi, %rax
    ret
.L4:    # x <= y
    movq    %rsi, %rax
    subq    %rdi, %rax
    ret

goto 语句

例子:

// Do While 的 C 语言代码
long pcount_do(unsigned long x)
{
    long result = 0;
    do {
        result += x & 0x1;
        x >>= 1;
    } while (x);
    return result;
}

// Goto 版本
long pcount_goto(unsigned long x)
{
    long result = 0;
loop:
    result += x & 0x1;
    x >>= 1;
    if (x) goto loop;
    return result;
}
    movl    $0, %eax    # result = 0
.L2:                    # loop:
    movq    %rdi, %rdx
    andl    $1, %edx    # t = x & 0x1
    addq    %rdx, %rax  # result += t
    shrq    %rdi        # x >>= 1
    jne     .L2         # if (x) goto loop
    rep; ret

switch 语句

long switch_eg (long x, long y, long z){
	long w = 1;
	switch (x) {
		case 1:
			w = y*z;
			break;
		case 2:
			w = y/z;
			// fall through
		case 3:
			w += z;
			break;
		case 5:
		case 6:
			w -= z;
			break;
		default:
			w = 2;
	}
	return w;
}

栈结构

栈

例子相应代码:

// multstore 函数
void multstore (long x, long, y, long *dest)
{
    long t = mult2(x, y);
    *dest = t;
}

// mult2 函数
long mult2(long a, long b)
{
    long s = a * b;
    return s;
}

汇编后:

0000000000400540 <multstore>:
    # x 在 %rdi 中,y 在 %rsi 中,dest 在 %rdx 中
    400540: push    %rbx            # 通过压栈保存 %rbx
    400541: mov     %rdx, %rbx      # 保存 dest
    400544: callq   400550 <mult2>  # 调用 mult2(x, y)
    # t 在 %rax 中
    400549: mov     %rax, (%rbx)    # 结果保存到 dest 中
    40054c: pop     %rbx            # 通过出栈恢复原来的 %rbx
    40054d: retq                    # 返回

0000000000400550 <mult2>:
    # a 在 %rdi 中,b 在 %rsi 中
    400550: mov     %rdi, %rax      # 得到 a 的值
    400553: imul    %rsi, %rax      # a * b
    # s 在 %rax 中
    400557: retq                    # 返回

递归

例子:

long pcount_r(unsigned long x) {
	if (x == 0)
		return 0;
	else
		return (x & 1) + pcount_r(x >> 1);
}

对应汇编:

pcount_r:
    mov     $0, %eax
    testq   %rdi, %rdi
    je      .L6
    push    %rbx
    movq    %rdi, %rbx
    andl    $1, %ebx
    shrq    %rdi
    call    pcount_r
    addq    %rbx, %rax
    popq    %rbx
.L6:
    rep; ret

结构体

结构体如果是这样

struct rec 
{
    int a[4];
    size_t i;       
    struct rect *next;
};

则在机器内部分配内存时为:
在这里插入图片描述
如果是这样

struct S1
{
    char c;
    int i[2];
    double v;
} *p;

则为

(参考于小土刀。不周山)

总结

第三章主要是讲一些基础的汇编知识点,教会学生如何看简单的汇编代码。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值