汇编常用命令总结

一、jmp    $
    $代表当前的地址
    那JMP $"就是跳转到当前的地址, 所以它是一个死循环,不继续执行下面的程序了。
    他的意思在于我要求的所有任务已经完成了,后面没有任务了,那么,就原地踏步吧!
    
    
二、xor eax,eax
是异或运算,两数相反为1;两数相同为0。由于这两个数相同,异或后等于清0
由于它比mov eax,0效率高,所以一般用它!

三、DA_C + DA_32
https://blog.csdn.net/bfboys/article/details/52435556

四、寄存器
1、8086cpu有十四个寄存器
    AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW
2、通用寄存器
    AX、BX、CX、DX
    AX 可分为 AH 和 AL
    BX 可分为 BH 和 BL
    CX 可分为 CH 和 CL
    DX 可分为 DH 和 DL

3、段寄存器
    CS、DS、SS、ES
    CS (Code Segment) 代码段
    DS (Data Segment) 数据段
    ES (Extra Segment) 附加段
    SS (Stack Segment) 栈段
    
4、CS 和 IP 
    CS 和 IP 是 8086CPU 中两个最关键的寄存器,它们指示了 CPU 当前要读取指令的地址。
    CS 为代码段寄存器, IP 为指令指针寄存器,从名称上我们可以看出它们和指令的关系。
    在 8086PC 机中,任意时刻,设 CS 中的内容为 M , IP 中的内容为 N , 8086CPU 将从内存 Mxl6 + N 单元开始,读取一条指令并执行。
    也可以这样表述: 8086 机中,任意时刻, CPU 将 Cs : IP 指向的内容当作指令执行。
    
5、ds: 通常用来存放用访问数据的段地址
    比如我们要读取10000H单元的内容
    mov bx, 1000H
    mov ds, bx   ;8086CPU不支持将数据直接送入段寄存器的操作,ds是一个段寄存器,所以需要一个寄存器来进行中转
    mov al, [0]
    [..] 表示一个内存单元
    
6、SS 和 SP
    8086CPU 中,有两个寄存器,段寄存器 SS 和寄存器 SP ,栈顶的段地址存放在 SS 中,偏移地址存放在 SP 中。
    任意时刻, SS:SP 指向栈顶元素。 push指令和pop指令执行时, CPU 从 SS 和 SP 中得到栈顶的地址。
    push ax 表示将AX寄存器的内容送入栈中, pop ax 表示从栈顶取出数据送入AX寄存器中。
    栈顶是低地址单元, 栈底是高地址单元。 
    1. push 指令的执行步骤:
        (1) SP = SP - 2 (偏移地址减少,即往低地址处偏移[栈顶方向])
        (2) 向SS:SP指向的字单元中送入数据 
    2. pop 指令的执行步骤:
        (1) 从SS:SP指向的字单元中读取数据
        (2) SP = SP + 2  (偏移地址增加,即往高地址处偏移[栈低方向]) 

7、FS 和 GS
fs,gs是80386起增加的两个辅助段寄存器,在这之前只有一个辅助段寄存器ES,增加这两个寄存器是为了减轻ES寄存器的负担,并能更好地配合适用于通用寄存器组的基址和变址寄存器.
这两个是通用的段寄存器,语法上同其它的段寄存器一样,不能直接用立即数给它赋值。

8、Loop 和 CX 
    Loop 循环指令执行前会将 cx = cx-1  cx不为0,这执行循环。所以可以用cx来实现循环控制
    
9、inc
    inc 就是目标数加一,类似于i++
    
10、$ 和 $$
    $:当前行被汇编之后的地址,是实际的线性地址
    $$:一个section的开始地方被汇编以后的地址,也是实际的线性地址
    
11、MOVZX 
    movzx一般用于将较小值拷贝到较大值中,并且其余位用0填充
    
12、SI 和 DI 和 LODSB
    SI是源变址寄存器,DI是目的变址寄存器。可以用来存放数据、地址,功能类似、用法类似、一般使用哪个都可以
    但需要注意的是:在串处理指令中,SI用作隐含的源串地址,默认在DS中;DI用做隐含的目的串地址,默认在ES中;此时不能混用。
    
13、LODSB 和 LODSW
    串操作指令LODSB/LODSW是块读出指令,其具体操作是把SI指向的存储单元读入累加器,
    其中LODSB是读入AL,LODSW是读入AX中,然后SI自动增加或减小1或2位.当方向标志位DF=0时,则SI自动增加;DF=1时,SI自动减小
    https://www.cnblogs.com/huzhongzhong/archive/2011/08/01/2123743.html
    
14、OF/DF/IF/TF/SF/ZF/AF/PF/CF
    这些都对应程序状态字寄存器PSW中序号0~11的标志位 用 0/1表示是否有效 分两大类
    1、条件标志:反映包含在ALU算术逻辑运算后的结果特征
        OF 溢出标志 :运算时,若操作数超出了机器所能表示的范围为,则产生溢出,OF=1,否则OF=0
        SF 符号标志 ;设置成运算操作结果的符号状态。当结果为负时,SF=1,否则SF=0
        ZF 零标志 结果=0,ZF=1,结果≠0,ZF=0
        AF 辅助进位标志 ,运算过程中第三位有进位,置AF=1,否则AF=0
        PF 奇偶标志: 当操作数中有偶数个1时,置PF=1,否则PF=0
        CF进位标志 : 最高有效位产生的进位值,例如 执行加法指令时,MSB有进,置CF=1;否则CF=0
    2、控制标志:控制执行特殊的功能
        DF放向标志:用于字符串操作指令程序设计。
        DF置0,则串操作控制处理方向,从带有最低地址的第一个元素逐个处理,否则,从高向低
        ID中断允许标志: IF=1,CPU允许中断,IF=0,则CPU关闭中断
        TF跟踪标志:TF=1,机器进入单步工作方式,每条机器指令执行后,显示结果及寄存器状态,若TF=0,则机器处在连续工作方式。此标志为调试机器或调试程序发现故障而设置。
15、TEST
    Test命令将两个操作数进行逻辑与运算,并根据运算结果设置相关的标志位。
    但是,Test命令的两个操作数不会被改变。运算结果在设置过相关标记位后会被丢弃。
    TEST指令会根据操作数运算的结果设置CF,OF,AF,SF,ZF,PF标志。
    例子:TEST al, al
        当AL为0时,SF=0, ZF=1, PF=1
        当AL为1时,SF=0, ZF=0, PF=0
        
16、cld 和 std
    CLD与STD是用来操作方向标志位DF(Direction Flag)。
    CLD使DF复位,即DF=0,STD使DF置位,即DF=1.用于串操作指令中。
    
17、ret 和 retf
    ret指令用栈中的数据,修改ip的内容,从而实现近转移
    retf指令用栈中的数据,修改cs和ip的内容,从而实现远转移
    cpu执行ret指令时,相当于进行
        pop IP 
    cpu执行retf指令时,相当于进行
        pop IP
        pop CS
    
    ret是子程序的返回指令
    reti是中断返回,并且清中断标志,以保证能继续中断.
    
18、push 和 pop
    push 寄存器   ;将一个寄存器中的数据入栈
    pop  寄存器      ;出栈,用一个寄存器接受出栈的数据
    
19、call 指令
    cpu执行call指令时,进行两步操作
    1、将当前的IP 或 CS和IP压入栈中
    2、转移

20、跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等
    跳转指令分三类:
    一、无条件跳转: JMP;
    二、根据 CX、ECX 寄存器的值跳转: JCXZ(CX 为 0 则跳转)、JECXZ(ECX 为 0 则跳转);
    三、根据 EFLAGS 寄存器的标志位跳转, 这个太多了.
        JE   ;等于则跳转
        JNE  ;不等于则跳转

        JZ   ;为 0 则跳转
        JNZ  ;不为 0 则跳转

        JS   ;为负则跳转
        JNS  ;不为负则跳转

        JC   ;进位则跳转
        JNC  ;不进位则跳转

        JO   ;溢出则跳转
        JNO  ;不溢出则跳转

        JA   ;无符号大于则跳转
        JNA  ;无符号不大于则跳转
        JAE  ;无符号大于等于则跳转
        JNAE ;无符号不大于等于则跳转

        JG   ;有符号大于则跳转
        JNG  ;有符号不大于则跳转
        JGE  ;有符号大于等于则跳转
        JNGE ;有符号不大于等于则跳转

        JB   ;无符号小于则跳转
        JNB  ;无符号不小于则跳转
        JBE  ;无符号小于等于则跳转
        JNBE ;无符号不小于等于则跳转

        JL   ;有符号小于则跳转
        JNL  ;有符号不小于则跳转
        JLE  ;有符号小于等于则跳转
        JNLE ;有符号不小于等于则跳转

        JP   ;奇偶位置位则跳转
        JNP  ;奇偶位清除则跳转
        JPE  ;奇偶位相等则跳转
        JPO  ;奇偶位不等则跳转
        
        
21、db 'hello',0 中0的意思
    用 C 语言定义字符串时,编译软件会自动在字符串的末尾,加上一个零。作为字符串结束的标记。
    用汇编的 DB 伪指令定义字符串,编译软件就没有自动加上零的功能。
    如果编程者想要加上零,就必须在程序中,自己加上零。
    hello是单词。最后会加0,这个0是字符串结束字符,以后处理的时候有用。
    
22、tims
    BootMessage:        db    "Hello, OS world!"
    times     510-($-$$)    db    0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
    dw     0xaa55              ; 结束标志

    times 123 db 0 ; 这个表示填充123个字节的0
    所以,times 510-($-$$) db 0 表示填充 510-($-$$) 这么多个字节的0
    这里面的$表示当前指令的地址,$$表示程序的起始地址(也就是最开始的7c00),所以$-$$就等于本条指令之前的所有字节数。
    510-($-$$)的效果就是,填充了这些0之后,从程序开始到最后一个0,一共是510个字节。再加上最后的dw两个字节(0xaa55是结束标志),
    整段程序的大小就是512个字节,刚好占满一个扇区。
    bootmessage: db "hello,os world!"
    这是说,紧跟着上一行ret指令的后面保存一个字符串,并且把它的地址标记为bootmessage,前面就可以使用这个字符串了(mov ax,bootmessage)
    times 510-($-$$) db 0 在刚才的字符串后面填充0
    ret是子程序的返回指令
    

转载于:https://my.oschina.net/yangshj/blog/3057464

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值