汇编总结: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的种类及其作用

练习题

时间: 2024-12-10 09:29:57

汇编总结: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和mov指令的区别

现在总结一下:其中牵扯到lea指令,mov指令,[] 一.lea指令:对于寄存器来说:第二个操作数是寄存器必须要加[],不然报错,这里lea就是取[寄存器]的值,如:mov eax,2lea ebx,[eax];执行后ebx=2mov ebx,eax;等同于上句lea ebx,eax;编译器报错: error A2070: invalid instruction operands 对于变量来说加不加[]都是一样的效果,都是取变量的地址,相当于指针如:num dword 2lea ebx,numl

汇编,寄存器,内存,mov指令

一.代码 和 汇编 和 二进制之间的关系 二.复习一下计算机组成原理的知识 1.寄存器 计算机中有三个存储 32位cpu提供的寄存器有三种类型8位 16位 32位 64位的只是32位的扩展 并且程序大多是32位 以下是32位的8个通用寄存器(有宽度) 2.MOV指令 mov eax ,1(向eax寄存器存1) mov  edx , eax(把edx里面的值存到eax) 例子:  EAX:32位通用寄存器 假如FFFFFFFF   一个F(16进制)化为2进制 1111,也就是4位 所以为什么叫3

汇编语言中LEA与MOV指令小结

 LEA指令的功能是取偏移地址,MOV指令的功能是传送数据  LEA AX,[1000H],作用是将内存单元[1000H]的偏移地址1000H送至AX: MOV AX,[1000H],作用是将内存单元[1000H]的内容1234H送给AX LEA AX,[SI],作用是将寄存器SI的内容4567H当做数据传送给AX: MOV AX,[SI],作用是将寄存器SI的内容4567H当做地址看待,将地址为4567H处的内容传送给AX: LEA AX,SI,作用是将寄存器SI的偏移地址1001H传送给AX

总结一下汇编中mov,lea指令的区别

最近在学习汇编语言,过程中遇到很多问题,对此在以后的随笔会逐渐更新,这次谈谈mov,lea指令的区别 一,关于有没有加上[]的问题 1,对于mov指令来说: 有没有[]对于变量是无所谓的,其结果都是取值 如: num dw 2 mov bx,num mov cx,[num]:bx=cx=2 对于寄存器而言,有[]表示取地址,没[]表示取值 如: num dw 2 mov ax,num mov bx,ax;bx=2 mov bx,[ax];mov bx;DS:[ax],这里可能存在报错的情况,总之

LEA指令与MOV指令的区别

一.汇编语言中PTR的含义及作用mov ax,bx ;是把BX寄存器"里"的值赋予AX,由于二者都是word型,所以没有必要加"WORD"mov ax,word ptr [bx];是把内存地址等于"BX寄存器的值"的地方所存放的数据,赋予ax.由于只是给出一个内存地址,不知道希望赋予ax的,是byte还是word,所以需要用word明确指出! 所以,当两个操作数的宽度不一样时,就要用到ptr.也就是说*p 用汇编表示就是:dword ptr [p

汇编中的指令对齐

title: 汇编中的指令对齐 tags: ARM date: 2018-10-23 20:50:39 --- 汇编中的指令对齐 搜索下官方文档的索引.align,有如下描述,也就是有两种情况,对于ARM,表示的是末尾几个0,也就是2^x了.具体填充格式可以指定align abs-expr, abs-expr, abs-expr,参考链接 For other systems, including ppc, i386 using a.out format, arm and strongarm, i

汇编跳转指令B、BL、BX、BLX 和 BXJ的区别

跳转指令用于实现程序流程的跳转,在 ARM 程序中有两种方法可以实现程序流程的跳转: (1) 使用专门的跳转指令. (2) 直接向程序计数器 PC 写入跳转地址值. 通过向程序计数器 PC 写入跳转地址值,可以实现在 4GB 的地址空间中的任意跳转,在跳转之前结合使用 MOV LR , PC 等类似指令,可以保存下一条指令地址作为将来的返回地址值,从而实现在 4GB 连续的线性地址空间的子程序调用. 专门的跳转指令 B.BL.BX.BLX 和 BXJ: 跳转.带链接跳转(带返回的跳转).跳转并切