美文网首页
每日总结-第十天(汇编考试准备)

每日总结-第十天(汇编考试准备)

作者: SamiraG | 来源:发表于2020-04-10 22:07 被阅读0次

使用gcc生成AT&T汇编风格的代码

gcc -S -o test.s test.c

与Intel相比

  • 寄存器前冠以“%”,而立即数前冠以“$”
  • 目标操作数在源操作数的右边mov $1, a ==> a=1, sub 1,a ==> a=a-1
  • 操作数的字长由操作符的最后一个字母决定
  • 内存寻址movw array(%base, %index, scale), %cx ==> cx=base+index*scale(scale等于1, 4 or 8
  • intel中基地址使用“[” 、“]” ,而在 AT&T 中使用“(”、“)” ;另外处理复杂操作数的语法 也 不同 , intel为 Segreg:[base+index*scale+disp], 而在 AT&T 中为%segreg:disp(base,index,sale),其中segreg,index,scale,disp都是可选的,在指定index而没有显式指定Scale的情况下使用默认值 1。Scale和 disp不需要加前缀“&”
    内存操作数的语法及举例

cmp指令

cmp是比较指令,cmp的功能相当于减法指令(sub)。它不保存结果,只是影响相应的标志位。其他的指令通过识别这些被影响的标志位来得知比较结果。
cmp指令格式: cmp 操作对象1, 操作对象2
注意是计算 操作对象2 - 操作对象1,和sub的一样, 但不保存结果,只是根据结果修改相应的标志位。
flag寄存器

移位指令

;SHL(Shift Left): 逻辑左移
;SHR(Shift Right): 逻辑右移
;SAL(Shift Arithmetic Left): 算术左移
;SAR(Shift Arithmetic Right): 算术右移

;其中的 SHL 和 SAL 相同, 但 SHR 和 SAR 不同.

;SHL、SAL: 每位左移, 低位补 0, 高位进 CF
;SHR : 每位右移, 低位进 CF, 高位补 0
;SAR : 每位右移, 低位进 CF, 高位不变

;它们的结果影响 OF、SF、ZF、PF、CF
;它们的指令格式相同:

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) gotoloop //注意这里
rep; ret # synonym of “ret”

JL/JG 和 JB/JA

JL: jump less 有符号小于跳转
JG: jump great 有符号大于
JB: jump below 无符号小于
JA: jump above 无符号大于
JLE/JNE...

switch指令汇编形式

  1. 条件判断
#include <algorithm>

int test_switch(){
    int i ;
    int a = std::rand();
    switch(a){
        case 0: i = 0;break;
        case 1: i = 1;break;
        case 2: i = 2;break;
        default: i = 3;break;
    }
    return i;
}

汇编

    movl    -4(%rbp), %eax
    cmpl    $1, %eax
    je  .L3
    cmpl    $2, %eax
    je  .L4
    testl   %eax, %eax
    jne .L8
    movl    $0, -8(%rbp)
    jmp .L6
.L3:
    movl    $1, -8(%rbp)
    jmp .L6
.L4:
    movl    $2, -8(%rbp)
    jmp .L6
.L8:
    movl    $3, -8(%rbp)
    nop
  1. 逐条件判断法
#include <algorithm>

int test_switch(){
    int i ;
    int a = std::rand();
    switch(a){
        case 0: i = 0;break;
        case 1: i = 1;break;
        case 2: i = 2;break;
        case 3: i = 3;break;
        case 4: i = 4;break;
        case 5: i = 5;break;
        case 6: i = 6;break;
        case 7: i = 7;break;
        case 8: i = 8;break;
        case 9: i = 9;break;
        default: i = 10;break;
    }
    return i;
}

汇编

    movl    -4(%rbp), %eax
    movq    .L4(,%rax,8), %rax
    jmp *%rax
.L4:
    .quad   .L3
    .quad   .L5
    .quad   .L6
    .quad   .L7
    .quad   .L8
    .quad   .L9
    .quad   .L10
    .quad   .L11
    .quad   .L12
    .quad   .L13
    .text
.L3:
    movl    $0, -8(%rbp)
    jmp .L14
.L5:
    movl    $1, -8(%rbp)
    jmp .L14
...
  1. 二分查找
#include <algorithm>

int test_switch(){
    int i ;
    int a = std::rand();
    switch(a){
        case 4: i = 4;break;
        case 10: i = 10;break;
        case 50: i = 50;break;
        case 100: i = 100;break;
        case 200: i = 200;break;
        case 500: i = 500;break;
        default: i = 0;break;
    }
    return i;
}

汇编

        movl    -4(%rbp), %eax
    cmpl    $50, %eax
    je  .L3
    cmpl    $50, %eax
    jg  .L4
    cmpl    $4, %eax
    je  .L5
    cmpl    $10, %eax
    je  .L6
    jmp .L2
.L4:
    cmpl    $200, %eax
    je  .L7
    cmpl    $500, %eax
    je  .L8
    cmpl    $100, %eax
    je  .L9
    jmp .L2

栈结构


函数调用时的栈结构




gdb指令

gdb$ p *(int *)($rbp-0x14) //打印$rbp-0x14处地址中存储的值
gdb$ x /x $rbp-0x14 //same

mov指令与lea指令

lea指令不解引用

mov 8(%rbp), rdi   --> rdi = *($rbp+8)
lea 8(%rbp), rdi    --> rdi = ($rbp + 8)

test指令

test属于逻辑运算指令
功能: 执行BIT与BIT之间的逻辑运算
测试(两操作数作与运算,仅修改标志位,不回送结果).
Test对两个参数(目标,源)执行AND逻辑操作,并根据结果设置标志寄存器,结果本身不会保存。EST AX,BX 与 AND AX,BX 命令有相同效果
语法: TEST r/m,r/m/data
影响标志: C,O,P,Z,S(其中C与O两个标志会被设为0)

运用举例:
1.Test用来测试一个位,例如

test eax, 100b; b表示二进制
jnz **; 如果eax右数第三个位为1,jnz将会跳转

2.Test的一个非常普遍的用法是用来测试一方寄存器是否为空:

test ecx, ecx 
jz somewhere

如果ecx为零,设置ZF零标志为1,Jz跳转

寄存器

直接跳转&间接跳转

直接跳转:跳转目标是作为指令封一部分编码。
间接跳转:目标是从寄存器或存储器位置读出来的。

typdef

#define ZLEN 5
typedef int zip_dig[ZLEN];
zip_dig cmu= { 1, 5, 2, 1, 3 }; //zip_dig cmu相当于int cmu[5]

二维数组的存储


A[i][j]的地址A+(i*C*4)+(j*4)
指针数组版本

结构体和偏移


如果结构体中最大的对齐要求是k那么总结构体的大小一定是k的倍数
eg

struct S1{
    double v;
    int a[2];
    char c;
};
//结构体大小为24(double的倍数)而不是17/18
struct S1{
    double v;
    char c[4];
};
//结构体大小是16(double的倍数)而不是12

Union

只分配最大的变量的存储空间,一次只允许使用一个值。


ISA

一个处理器支持的指令和指令的字节级编码称为它的指令集体系结构(Instruction-Set Architecture,ISA)


Y86-64指令集

https://www.cnblogs.com/ysocean/p/7686213.html
http://hczhcz.github.io/2014/06/13/y86-instruction-set.html

HCL

https://www.cnblogs.com/ysocean/p/7686219.html

  • 门电路
  • MUX & ALU
  • 寄存器与存储器

大多数时候,寄存器都保持在稳定状态(用x表示),产生的输出等于它的当前状态,信号沿着寄存器前面的组合逻辑传播,这时产生了一个新的寄存器输入(用y表示),但是只要时钟信号是低电位的,寄存器的输出就保持不变。当时钟变为高电位时,输入信号就加载到寄存器中,称为下一个状态y,直到下一个时钟上升沿,这个状态就一直是寄存器的新输出。

SEQ CPU

https://blog.csdn.net/dennis_fan/article/details/8284248

相关文章

  • 每日总结-第十天(汇编考试准备)

    使用gcc生成AT&T汇编风格的代码 与Intel相比 寄存器前冠以“%”,而立即数前冠以“$” 目标操作数在源操...

  • 请一天假,光明正大的摸鱼

    这是因疫情居家办公的第十天,我已经不知道怎么摸鱼了,早上对着电脑,准备写写领导要求的每日工作计划和总结,但...

  • IOS arm64常用的汇编

    导论 生成汇编文件 寄存器 arm64 汇编条件域 arm64 汇编指令 总结 1. 生成汇编文件 2. 寄存器 ...

  • 汇编总结

    为了表示我对简书『饱醉豚』事件的不满,简书不再更新,后续有文章只更新 个人博客和 掘金 欢迎移步 个人博客或者 掘...

  • 汇编学习总结

    汇编总结 汇编的发展史 机械语言 由0和1组成的机器指令(如:0101 0001 1101 0110) 汇编语言(...

  • 【每日精进】准备明天的考试

    5月30日星期一,天气:晴好 早晨:5点不到起床;完成早起事务;提交全部图片给编辑,等候修改意见吧。 上午:仅得完...

  • 2018-05-29 三周分手GRE:V162 Q170

    一个简短的GRE复习总结 考试时间:2018/5/27 考试结果:V162 Q170 作文3.5 考试准备流程:...

  • JVM汇编总结

    无关性的基石 计算机只认识0和1,所以我们写的程序需要被编译器翻译成0和1才能被计算机执行。10多年的时间过去了,...

  • 汇编总结(一)

    汇编的定位 通俗理解:汇编语言是高级语言与机器语言之间的语言,所有的高级语言在运行在终端设备上之前,都要先编译成汇...

  • 考试准备

    写了自己大概要干嘛

网友评论

      本文标题:每日总结-第十天(汇编考试准备)

      本文链接:https://www.haomeiwen.com/subject/frwkmhtx.html