汇编总结:mov指令

mov指令的作用:

mov指令可能是汇编里用的最多的指令了,完成c语言里的赋值。

mov指令种类:

普通的mov指令
做符号扩展的movs
做零扩展的movz

普通mov的种类有:

movb #完成1个字节的复制
movw #完成2个字节的复制
movl #完成4个字节的复制
movq #完成8个字节的复制

movs的种类以及为什么要符号扩展指令?

1.为什么要用符号扩展指令

如果要完成下面的c语言代码

char c = -1;
int i = c;

如果翻译成下面的汇编代码,会发现一个问题

用movb把%al寄存器里的-1,复制到%ebx寄存器,结果变成了255。等等,为什么会这样?

.section .text
.global _start

fmt:
    .ascii "%d\n\0"

_start:
    movb $-1, %al      #把-1赋值到寄存器al
    xorl %ebx, %ebx    #把寄存器%ebx 赋值为0
    movb %al, %bl      #把al的值赋值到%ebx寄存器的低8位 (引用%ebx寄存器低8位的方法就是使用%bl寄存器)

    xorq %rax, %rax
    movl %ebx, %esi
    movq $fmt, %rdi
    call printf        #调用printf 打印ebx寄存器的内容,会发现输出变成了255

    movl $0, %edi      #调用exit退出进程
    call exit

接上段,学过原码,补码,反码的同学知道,在二进制的角度看待一个数。其在内存中表示正数,表示负数,依赖机器是怎么解释最高bit位的1。c语言里面signed类型,如果最高bit为1,认为它是一个负数。unsigned类型,始终认为是正数。

回到刚刚的-1变成255的问题。

作用用户,只想在由char 类型转为int,输出还是-1,就这么简单。

(事实上c语言已经做了自动转换,这里的char,int只是指代上面的汇编代码里的类型)

char类型的-1在内存中的表示:11111111

(由于最高bit位为1,且类型为signed,所以解释成-1)

使用movb指令把char类型的-1复制到int类型里:

char类型的-1复制到int类型在内存中的表示:00000000000000000000000011111111

(由于最高bit位为0,且类型为signed,所以解释成255)

int类型的-1在内存中的表示:11111111111111111111111111111111

两边一对比就知道,char复制到int需要把多出来的字节作符号位扩展。

2.movs的种类

movsbw #作符号扩展的1字节复制到2字节
movsbl #作符号扩展的1字节复制到4字节
movsbq #作符号扩展的1字节复制到8字节
movswl #作符号扩展的2字节复制到4字节
movswq #作符号扩展的2字节复制到8字节
movslq #作符号扩展的4字节复制到8字节

TODO:

movz的种类及其作用

练习题

时间: 09-13

汇编总结:mov指令的相关文章

基于8086CPU微处理器的汇编学习之MOV指令

汇编指令:MOV的作用是往某个寄存器中存入数值. 格式:mov  寄存器名,数值                数值-->寄存器 mov  寄存器A,存器寄B          B-->A PS:必须前后位数匹配,如: mov   ah,bx     ;error   ah is 8 bit,bx is 16 bit mov   ah, bh    ;right    ah and bh all is 8  bit mov   cx,dx     ;right     cx and dx al

汇编-MOV指令

知识点: ? MOV指令 ? 基址 ? 内联汇编 ? 把OD附加到资源管理器右键菜单 一.MOV指令 aaa=0x889977;//MOV DWORD PTR DS:[0x403018],0x889977 //dword 双字 就是四个字节 ptr pointer缩写 即指针 []里的数据是一个地址值 二.内联汇编 _asm aaa=0x889977;// __asm MOV DWORD PTR DS:[0x403018],0x889977 //不安全的写法 __asm mov aaa,0x88

汇编总结:lea指令

lea指令变种(按大小分类): leaw #2个字节 leal #4个字节 leaq #8个字节 lea的用法: leaq a(b, c, d), %rax 首先lea指令是mov指令的变种,据说,lea指令是x86体系结构中,是一条最古老但是从某个方面来讲又是最神奇的指令. 表面上看,它做的事情非常简单,根据括号里的源操作数来计算地址,然后把地址加载到目标寄存器中. 例如:leaq a(b, c, d), %rax 先计算地址a + b + c * d,然后把最终地址载到寄存器rax中. 最逗

汇编Lea 指令与 Mov 指令

比如你用local在栈上定义了一个局部变量LocalVar,你知道实际的指令是什么么?一般都差不多像下面的样子:     push   ebp     mov   esp,   ebp     sub   esp,   4     现在栈上就有了4各字节的空间,这就是你的局部变量.     接下来,你执行mov   LocalVar,   4,那么实际的指令又是什么?是这样:     mov   dword   ptr   [ebp-4],   4     于是,这个局部变量的“地址”就是ebp

《Intel汇编第5版》 Mov指令

一.Mov用于数据传送,用法如下: 二.当传送的数据和目标数据位宽不一致的时候,需要使用MOVZX.MOVSX扩展.MOVZX使用0填充高位,MOVSX使用源操作数最高位填充 下面是汇编代码演示: INCLUDE Irvine32.inc includelib Irvine32.lib includelib kernel32.lib includelib user32.lib .code ;无符号类型 var1 DWORD 12345678h ;有符号类型 var2 SDWORD 1234567

汇编语言学习:汇编指令:MOV指令

MOV指令为双操作数指令,两个操作数中不能全为内存操作数 格式:MOV DST,SRC 执行操作:dst <= src 注:1.目的数可以是通用寄存器,存储单元和段寄存器(但不允许用CS段寄存器). 2.立即数不能直接送段寄存器 3.不允许在两个存储单元直接传送数据 4.不允许在两个段寄存器间直接传送信息

汇编--算术运算类指令

加法指令:ADD.ADC.INC 减法指令:SUB.SBB.DEC.NEG.CMP 乘法指令:MUL.IMUL 除法指令:DIV.IDIV 十进制调整指令:DAA.DAS.AAA.AAS.AAM.AAD 加法指令: ADD 带进位加法指令:ADC 加一指令:   INC 注意: 除 INC 指令不影响 CF 标志外,均对条件标志位有影响. 结果为0   ZF=1       结果为负   SF=1 CF 位表示 无符号数 相加的溢出.   和的最高有效位 有 向高位的进位 OF 位表示 带符号数

arm学习之汇编跳转指令总结

目前所知道的跳转指令有 b,bl,bep,bne.他们共同点是都是以b开头,首先从字面上分析:b:是Branch,表示分支.bl:是Branch Link表示带连接的分支.bep:Branch ,Equalbne:Branch ,Not Equal. B或BL指令引起处理器转移到"子程序名"处开始执行.两者的不同之处在于BL指令在转移到子程序执行之前将其下一条指令的地址拷贝到R14(LR,链接寄存器).由于BL指令保存了下条指令的地址因此使用指令"MOV PC,LR&qu

汇编 push ,pop指令

知识点: ? PUSH ? POP ? CALL堆栈平衡 ? RETN指令 一.PUSH入栈指令 (压栈指令): 格式: PUSH 操作数 //sub esp,4 ;mov [esp],EBP 操作数可以是寄存器,存储器,或者立即数 二.POP出栈指令 (弹栈指令) 格式:POP 操作数 //mov EBP,[esp] ;add esp,4 操作数是寄存器,或者存储器,不能是立即数 三.代码分析 1.测试PUSH和POP 与ESP栈顶指针的关系 2.CALL与ESP的关系 3.总结栈的特点(后进