#2
zhulei19782016-07-02 16:50
|
我们学习的第一条汇编指令是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编辑过]