• 一命赌快乐 置顶
    2019-04-08
    move a b :把b值赋给a,使a=b
    call和ret :call调用子程序,子程序以ret结尾
    jmp :无条件跳
    int :中断指令
    add a b : 加法,a=a+b
    or :或运算
    xor :异或运算
    shl :算术左移
    ahr :算术右移
    push xxx :压xxx入栈
    pop xxx: xxx出栈
    inc: 加1
    dec: 减1
    sub a b : a=a-b
    cmp: 减法比较,修改标志位
    展开

    作者回复: 赞,认真学习的典范

     1
     129
  • Frank_51
    2019-04-08
    作为一个搞硬件的,这章是我学习最轻松的,推荐一个入门的系统学习汇编的视频课,网易云课堂上的一个课程,《汇编从零开始到C语言》,通俗易懂,小白入门必备

    作者回复: 推荐书籍

     2
     34
  • Colin.Tao
    2019-04-08
    妥妥地复习了一把“计算机体系结构”🌹

    作者回复: 后面很多地方要用到寄存器,所以必须先讲一下

    
     34
  • why
    2019-04-10
    - CPU 包括: 运算单元, 数据单元, 控制单元
        - 运算单元 不知道算哪些数据, 结果放哪
        - 数据单元 包括 CPU 内部缓存和寄存器, 暂时存放数据和结果
        - 控制单元 获取下一条指令, 指导运算单元取数据, 计算, 存放结果
    - 进程包含代码段, 数据段等, 以下为 CPU 执行过程:
        - 控制单元 通过指令指针寄存器(IP), 取下一条指令, 放入指令寄存器中
            - 指令包括操作和目标数据
        - 数据单元 根据控制单元的指令, 从数据段读数据到数据寄存器中
        - 运算单元 开始计算, 结果暂时存放到数据寄存器
    - 两个寄存器, 存当前进程代码段和数据段起始地址, 在进程间切换
    - 总线包含两类数据: 地址总线和数据总线
    ---
    - x86 开放, 统一, 兼容
    - 数据单元 包含 8个 16位通用寄存器, 可分为 2个 8位使用
    - 控制单元 包含 IP(指令指针寄存器) 以及 4个段寄存器 CS DS SS ES
        - IP 存放指令偏移量
        - 数据偏移量存放在通用寄存器中
        - `段地址<<4 + 偏移量` 得到地址
    ---
    - 32 位处理器
    - 通用寄存器 从 8个 16位拓展为 8个 32位, 保留 16位和 8位使用方式
    - IP 从 16位扩展为 32位, 保持兼容
    - 段寄存器仍为 16位, 由段描述符(表格, 缓存到 CPU 中)存储段的起始地址, 由段寄存器选择其中一项
        - 保证段地址灵活性与兼容性
    ---
    - 16位为实模式, 32位为保护模式
    - 刚开机为实模式, 需要更多内存切换到保护模式
    展开
    
     17
  • why
    2019-04-08
    Guide to x86 Assembly: http://www.cs.virginia.edu/~evans/cs216/guides/x86.html

    作者回复: 赞

    
     13
  • 谭
    2019-04-08
    老师讲地太精彩了 点赞。由于基础弱,还有几个问题希望老师万忙中答疑一下,谢谢:

    问题1:程序编译成二进制代码的时候,包含有指令起始地址吗?若包含那么后续每一行指令的涉及到的指令地址是计算出来的? 或者说加载进程的程序的时候才会确定起始地址?很好奇这个指令的指针寄存器里的值是什么时候、怎么放进去的?

    问题2: CPU两个寄存器处理保存当前进程代码段的起始地址,已经数据起始地址。切换进程时会将这两个寄存器里的值一并切换,那么同一个进程出现多线程的时候了?

    问题3:数据总线拿数据的时候没有限制大小吗,若数据很大,数据单元里的数据寄存器放不下怎么办的?
    展开

    作者回复: 1.会有指令起始地址,后面讲ELF格式的时候会说这个事情。当执行一个程序的时候,会加载ELF格式,加载的时候会设置指令指针
    2.多线程共享同一个进程内存空间,所以代码段的起始地址还是一样的。只不过每个线程执行不同的func,指令指针会不一样,在内核中,线程也是有独立的task_struct
    3.寄存器是有限的,如果把程序编译成汇编看的话,再大的数据,也是要转换为对寄存器的操作。当然寄存器里面可以包含对内存的访问地址,这样内存里面的数据就很多了

    
     12
  • MJ
    2019-04-08
    “起始地址 *16+ 偏移量”,也就是把 CS 和 DS 中的值左移 4 位,变成 20 位的,加上 16 位的偏移量,这样就可以得到最终 20 位的数据地址。

    求问老师,左移四位,如何理解?

    作者回复: 就是乘以十六

     2
     12
  • TeFuir
    2019-04-09
    老师您好,我想问下 为什么高16位分成两个8位就不兼容列呀。

    作者回复: 没有人写程序用高位的

    
     10
  • Pluto
    2019-04-08
    原来 x86 架构是指 8086 ,而 x86 是代表 32 位操作系统是因为 80386,原来这两个 x86 不是同一个意思啊,以前学操作系统的时候一直想不明白 x86 为什么是指代 32 位操作系统

    作者回复: 哈哈

     1
     8
  • MARK
    2019-04-08
    已经有童鞋回复,再补充点
    MOV: load value. this instruction name is misnomer, resulting in some confusion (data is not movedbut copied), in other architectures the same instructions is usually named “LOAD” and/or “STORE”or something like that.One important thing: if you set the low 16-bit part of a 32-bit register in 32-bit mode, the high 16bits remains as they were. But if you modify the low 32-bit part of the register in 64-bit mode, thehigh 32 bits of the register will be cleared.Supposedly, it was done to simplify porting code to x86-64.

    CALL:call another function:PUSH address_after_CALL_instruction; JMP label.
    JMP: jump to another address. The opcode has ajump offset.

    INT(M):INT x is analogous to PUSHF; CALL dword ptr [x*4]in 16-bit environment. It was widely used in MS-DOS, functioning as a syscall vector. The registers AX/BX/CX/DX/SI/DI were filled with the arguments and then the flow jumped to the address in the Interrupt Vector Table (located at thebeginning of the address space). It was popular because INT has a short opcode (2 bytes) and the program which needs some MS-DOS services is not bother to determine the address of the service’sentry point. The interrupt handler returns the control flow to caller using the IRET instruction.The most busy MS-DOS interrupt number was 0x21, serving a huge part of itsAPI. In the post-MS-DOS era, this instruction was still used as syscall both in Linux and Windows (6.3 onpage 750), but was later replaced by the SYSENTER or SYSCALL instructions.

    RET: return from subroutine:POP tmp; JMP tmp.
        In fact, RET is an assembly language macro, in Windows and *NIX environment it is translated into RETN (“return near”) or, in MS-DOS times, where the memory was addressed differently, into RETF (“return far”).
        RET can have an operand. Then it works like this:
        POP tmp; ADD ESP op1; JMP tmp.RETwith an operand usually ends functions in the stdcall calling convention.
    展开
    
     6
  • YoungMarshual_besos
    2019-04-08
    几乎完全看懵了,发现基础知识极其匮乏,努力补课,夯实根基太重要了。

    作者回复: 补充完再看,可以看看计算机组成与系统结构

    
     6
  • 布凡
    2019-04-12
    本文结构:https://www.cnblogs.com/bindot/p/linux6.html
    
     5
  • Matnix
    2019-04-11
    结合《深入理解计算机系统》第三章,受益匪浅

    作者回复: 这本书值得推荐

    
     5
  • TinnyFlames
    2019-04-08
    x86是甜蜜的历史包袱,它的兼容性让它一统市场,但是当时很多性能上更好的尝试在商业上都失败了,因为兼容性的问题客户不买单……

    作者回复: 是的,所以兼容比优雅要重要

    
     5
  • 楽天
    2019-05-08
    那64位的还有实模式吗?

    作者回复: 有的

    
     3
  • 学徒王小明
    2019-04-10
    微软的IDE visual studio,可以查看C语言编译后的汇编语言,内存,寄存器,非常方便。

    作者回复: 好久没用vs了,只要能够帮助理解,就是好工具

    
     3
  • 尚墨
    2019-04-10
    上周看了 Go 夜读社区 《Go Plan 9汇编入门》https://www.bilibili.com/video/av46494102 听的云里雾里的,在来看这篇文章好像感觉出了点门道。

    作者回复: 呜哇,没想到能和go联系在一起,看来底层原理比较容易互通

    
     3
  • MARK
    2019-04-08
    补充2
    ADD: add two values.    
    OR: logical “or”.
    XOR op1, op2:is in fact just “eXclusive OR”,but the compilers often use it instead of MOV EAX, 0—again becauseit is a slightly shorter opcode (2 bytes for XOR against 5 for MOV).

    SHL/SHR: shift value left/right.
       Bit shifts in C/C++ are implemented using≪and≫operators. The x86 ISA has the SHL (SHift Left) and SHR (SHift Right) instructions for this. Shift instructions are often used in division and multiplications bypowers of two:2n(e.g., 1, 2, 4, 8, etc.): Shifting operations are also so important because they are often used for specific bit isolation or forconstructing a value of several scattered bits.

    PUSH: push a value into the stack:ESP=ESP-4 (or 8); SS:[ESP]=value.
    POP: get a value from the stack:value=SS:[ESP]; ESP=ESP+4 (or 8).
        The most frequently used stack access instructions are PUSH and POP(in both x86 and ARM Thumb-mode).PUSH subtracts from ESP/RSP/SP4 in 32-bit mode (or 8 in 64-bit mode) and then writes the contents of its sole operand to the memory address pointed by ESP/RSP/SP.
        POP is the reverse operation: retrieve the data from the memory location that SP points to, load it into the instruction operand (often a register) and then add 4 (or 8) to the stack pointer.

    INC: increment. Unlike other arithmetic instructions,INC doesn’t modify CF flag.
    DEC: decrement. Unlike other arithmetic instructions,DEC doesn’t modify CF flag.
    SUB: subtract values. A frequently occurring pattern is SUB reg.
    CMP: compare values and set flags, the same as SUB but without writing the result.
    展开
    
     3
  • 佳佳大魔王
    2019-04-08
    实模式和保护模式的英文中模式应该为pattern吧,另外这两个模式不太理解。

    作者回复: 可以理解为,CPU和操作系统的一起干活的模式,在实模式下,两者约定好了这些寄存器是干这个的,总线是这样的,内存访问是这样的,在保护模式下,两者约定好了这些寄存器是干那个的,总线是那样的,内存访问是那样的。这样操作系统给CPU下命令,CPU按照约定好的,就能得到操作系统预料的结果,操作系统也按照约定好的,将一些数据结构,例如段描述符表放在一个约定好的地方,这样CPU就能找到。两者就可以配合工作了。

    
     3
  • Luciano李鑫
    2019-04-08
    准时
    
     3
我们在线,来聊聊吧