标签:
-ISA(Instruction set architecture)。ISA简单来说就是指令集体系结构。定义了处理机状态,指令格式以及指令对状态的影响。
-机器级使用的存储器地址是虚拟地址。
1.产生汇编代码文件:gcc -01 -S xxx.c
生成xxx.s文件
2.产生目标代码文件:gcc -01 -c xxx.c
生成xxx.o文件
3.查看目标代码文件的内容:objdump -d xxx.o
movb $0xf,(%bl)
.2.二元操作如sub,mov
中两个操作数不能同时是存储器位置 。addl、subl、andl、xorl
jmp、jle、jl、je、jne、jge、jg
cmovle、cmovl、cmove、cmovne、cmovge、cmovg
为单个过程分配的那部分栈称为栈帧(stack frame)。寄存器%ebp为帧指针,而寄存器%esp为栈指针。栈帧结构(栈用来传递参数、存储返回信息、保存寄存器,以及本地存储)
支持过程调用和返回的指令:
指令 描述
-call Label 过程调用
-call *Operand 过程调用
-leave 为返回准备栈
-ret 从过程调用中返回
call指令的效果是将返回地址入栈,并跳转到被调用过程的起始处。返回地址是在程序中紧跟在call后面的那条指令地址。
程序寄存器组是唯一能被所有过程共享的资源。虽然在给定时刻只能有一个过程是活动的,但是我们必须保证当一个过程(调用者)调用另一个过程(被调用者)时,被调用者不会覆盖某个调用者稍后会使用的寄存器的值。根据惯例,寄存器%eax、%edx和%ecx被划分为调用者保存寄存器。当过程P调用Q时,Q可以覆盖这些寄存器,而不会破任何P所需要的数据。另一方面,寄存器%ebx、%esi和%edi被划分为被调用者保存寄存器。这意味着Q必须在覆盖这些寄存器之前,先把它们保存到栈中,并在返回前恢复它们。
int decode2(int x ,int y, int z)
{
int a = z - y;
int b = (a << 15) >> 15;
return (x ^ a) * b;
}
typedef long long ll_t;
void store_prod(ll_t *dest, ll_t x, int y){
*dest = x*y;
}
// dest at %ebp+8, x at %ebp + 12, y at %ebp + 20
movl 12(%ebp), %esi //将x的低位存到%esi
movl 20(%ebp), %eax //将y存到%eax
movl %eax, %edx
sarl $31, %edx //将(y >> 31)存到%edx
movl %edx, %ecx
imull %esi, %ecx //计算x_low * (y >> 31)存到%ecx
movl 16(%ebp), %ebx //将x的高位存到%ebp
imull %eax, %ebx //计算x_high * y
addl %ebx, %ecx //计算 x_high * y + x_low * (y >> 31) 存到%ecx
mull %esi //计算y * x_low 的无符号64位乘积
leal (%ecx, %edx), %edx //将64位乘积的高位与x_high * y + x_low * (y >> 31)得到最终结果的高位
movl 8(%ebp), %ecx
movl %eax, (%ecx)
movl %edx, 4(%ecx) //将结果写入目的内存地址
说明:
该汇编代码其实是y扩展至64位再进行两个64位数的乘积然后进行截断得到的。
事实上有:
y *{signed} x =
(y_high * 2^32 + y_low) *{signed} (x_high * 2^32 + x_low) =
y_high *{signed} x_high * 2^64 +
y_high *{signed} x_low * 2^32 +
y_low *{signed} x_high * 2^32 +
y_low *{signed} x_low(有符号的x_low与无符号的x_low相等,故可用mull指令)
而y_high *{signed} x_high由于乘以2^64,所以对结果不会产生影响。
int loop(int x, int n)
{
int result = 0x55555555;
int mask;
for(mask = 0x80000000;mask !=0; mask = (unsigned)mask >> (n & 0xFF))
{
result ^= x & mask;
}
return result;
}
movl 20(%esp), %eax
movl $0, 12(%esp)
leal 12(%esp), %edx
testl %eax, %eax
cmove %edx, %eax
movl (%eax), %eax
addl $16, %esp
.cfi_def_cfa_offset 4
ret
int switch3(int *p1,int *p2,mode_t action)
{
int result = 0;
switch(action){
case MODE_A:
result = *p1;
*p1 = *p2;
break;
case MODE_B:
result = *p1 + *p2;
*p2 = result;
break;
case MODE_C:
*p2 = 15;
result = *p1;
break;
case MODE_D:
*p2 = *p1;
result = 17;
break;
case MODE_E:
result = 17;
break;
default:
result = -1;
break;
}
return result;
}
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/0 | 1/2 | 10/10 | |
第二周 | 300/300 | 1/3 | 20/30 | |
第三周 | 300/600 | 2/5 | 16/46 | |
第五周 | 300/900 | 1/6 | 15/61 |
标签:
原文地址:http://www.cnblogs.com/dwc929210354/p/5968125.html