[AT&T汇编语言]第五讲 MOV指令
前四讲其实都是在讲述编译环境方面的东西,从这一讲开始,我们真正开始编写汇编指令。我们学习的第一条汇编指令是MOV指令。在编写汇编指令时,大量的情况我们都是在使用MOV指令,可以说学会了MOV指令,就学会了一半的汇编语言。
MOV指令实现下面的功能:
1、寄存器和寄存器之间的传送
2、立即数到寄存器的传送
3、寄存器到内存单元之间的传送
4、立即数到内存单元的传送
汇编语言中的传送和实际生活中的传送有些区别。
实际生活中的传送是将某一物体从A地转移到B地,传送开始前、传送过程中、传送结束后,都只有一个事物,不会产生新的事物。
但汇编语言中的传送和C语言中的赋值是一个意义。从源位置传送到新位置,源位置的值不发生变化,而新位置的值会等于原位置的值,不论新位置之前是什么值。
下面看一个例子:
mov.s:
程序代码:
BOOT_SECT = 0x07c0 # 宏定义 .code16 # 将这个汇编代码编译成16位程序 .section .text # 这是代码段的内容 .global _start # 在目标文件中导出_start符号 _start: jmp $BOOT_SECT, $go # 跳转到0x07c0段 go: mov %cs, %ax # 初始化ds/es段寄存器 mov %ax, %ds mov %ax, %es mov %ax, %bx cpu_hlt: # 停止CPU hlt jmp cpu_hlt .org 510 # 启动扇区标志 .word 0xAA55
我们从bochs控制台中看到:
在mov %ax, %bx未执行前,ax中的值是0x07c0,bx中的值是0;执行后,ax中的值未发生变化,但bx中的值变成了0x07c0。
我们在mov %ax, %bx这一行的后面再新增一行:mov $0x1234, %cx
代码就变成了:
程序代码:
BOOT_SECT = 0x07c0 # 宏定义 .code16 # 将这个汇编代码编译成16位程序 .section .text # 这是代码段的内容 .global _start # 在目标文件中导出_start符号 _start: jmp $BOOT_SECT, $go # 跳转到0x07c0段 go: mov %cs, %ax # 初始化ds/es段寄存器 mov %ax, %ds mov %ax, %es mov %ax, %bx mov $0x1234, %cx cpu_hlt: # 停止CPU hlt jmp cpu_hlt .org 510 # 启动扇区标志 .word 0xAA55
我们从bochs控制台中看到:
在mov $0x1234, %cx未执行前,cx中的值是0x0;执行后,cx中的值变成了0x1234。
但我们不能让某一个寄存器的值赋值给一个立即数,这一点很好理解。立即数其实是个值,它本身是没有存储空间和存储能力的。
我们继续修改上面的代码:
程序代码:
BOOT_SECT = 0x07c0 # 宏定义 .code16 # 将这个汇编代码编译成16位程序 .section .text # 这是代码段的内容 .global _start # 在目标文件中导出_start符号 _start: jmp $BOOT_SECT, $go # 跳转到0x07c0段 go: mov %cs, %ax # 初始化ds/es段寄存器 mov %ax, %ds mov %ax, %es mov %ax, %bx mov $0x1234, %cx mov %cx, val cpu_hlt: # 停止CPU hlt jmp cpu_hlt val: .word 0x0 .org 510 # 启动扇区标志 .word 0xAA55汇编语言中声明一个变量使用的格式如下:
变量名:
变量类型 初始值
声明一个字节的变量,变量类型使用.byte;
声明两个字节的变量,变量类型使用.word;
声明四个字节的变量,变量类型使用.long;
我们从bochs控制台中看到:
在mov %cx, val未执行前,val中的值是0x0;执行后,val中的值变成了0x1234
以后对于变量的声明和引用,可以参照这个例子去做。
[此贴子已经被作者于2016-7-2 13:14编辑过]