通过两个汇编实例对高级语言数组实现原理的发现
2012-06-13 20:52
246 查看
先要介绍一下寻址,我们要运行一个程序,可执行文件先会被加载到内存里面,CPU通过寻址,去内存里面找到这段可执行文件的程序,然后把它的程序段通过总线运送会CPU进行计算。
既然是寻址,就要知道物理内存的地址。这个地址由两部分组成。段首地址和偏移地址。比方说,我有4个盒子,可以表示的信息量是2的四次幂,16个。我要有20个数据呢?怎么用四个盒子表示?就可以先用一种排列表示,然后再用一种排列表示,两种排列的顺序通过一定的约定,便可以表示20或者更多的数据了。
在计算机里的这一个约定是段首地址*16+偏移地址。
下面进入主题。
我们要把 BaSic和MinIx两个单词全部转化成大写字母。
在VB中,我们可以用Ucase函数,在C语言中常用的是每个字母的ASCII值减去32,在输出。
还有一种办法,通过把A,a,B,b等等的ascii二进制数写出来,找到一个规律。
大写字母和小写字母的二进制的区别是,大写字母第五位是0,小写是1。
所以在汇编语言中,我们利用的是逻辑and(与运算)和or(或运算)运算来实现大小写转换。
编写汇编代码
assume ds:data,cs:code
data segment
Db 'BaSic'
Db 'MinIx'
data ends
code segment
start:mov ax,data
Mov dx,ax
Mov bx,0
Mov cx,5
.注意下面的代码
s:Mov al,[bx]
And al,11011111
Mov [bx],al
Mov al,[bx+5]
Or al,00100000
Mov [bx+5],al
Inc bx
Loop s
._________________
mov ax,4c00h
int 21h
code ends
end start
程序段完了,那里的And al,11011111是为了把第五位的数组改成0,下面的同理。这里不是重点理解。
Mov al,[bx+5] 又可以写成 mov al,5[bx],Mov [bx+5],al 也可以写成mov 5[bx],al。是不是5[bx]这个和VB里面a()数组和C语言的a[]形式有点相似?如果还看不出来,我们用C语言写出中间那段程序。
Char a[5]="BaSic"
Char b[5]="MinIx"
main()
{
int i;
i=0;
Do
{
a[i]=a[i]&0xDF;
b[i]=b[i]|0x20;
i++;
}
While(i<5);
}
如果你熟悉C语言的话,可以比较这个C语言程序和上面汇编语言程序的相似之处。尤其注意它们定位字符串中字符的方式。
C语言:a[i],b[i]
汇编语言:0[bx],5[bx]
是不是可以看出什么。
当然,这还没有结束。
下面这个例子更为经典。
这是一个公司的数据:
公司名称:ABC
总裁名称:Abc Defgh
排名:100
收入:10亿
产品:LMN
这些都写在了内存里面。时隔几年后,数据有很多变了,我们要改变一些数据。比方说Abc Defgh的排名已经上升到38位,收入增加了70亿,产品变成了VAX系列计算机。
我们先用C语言写。
//下面先是定义,不做重点。
Struct company
{
Char cn[3];
Char hn[9];
Int pm;
Int sr;
Char cp[3];
}
Struct company dec{"ABC","Abc Defgh",100,10,"LMN"}
//下面是改数据的过程。
Main()
{
Int I;
Dec.pm=38;
Dec.sr=dec.sr+70
i=0;
Dec.cp='L';
i++;
Dec.cp='M';
i++;
Dec.cp='N';
Return 0;
}
用汇编语言写出改数据的部分就可以了。
Mov ax,seg
Mov ds,ax
Mov bx,60
.这里是重点
Mov word ptr [bx].0ch,38
Add word ptr [bx].0eh,70
Mov si,0
Mov byte ptr [bx].10[si],'L'
Inc si
Mov byte ptr [bx].10[si],'M'
Inc si
Mov byte ptr [bx].10[si],'N'
我们开始比较,C语言中的语句是Dec.cp='V',汇编语言中是.....[bx].10[si],'V'
在C语言中,我们看到,如: dec.cp[i],dec是一个变量名,指明了结构体变量的地址,cp是一个名称,指明了数据项cp的地址,而用i来定位cp中的每一个字符。汇编语言的做法是,bx.10[si]是不是很相似?
在熟悉的VB环境中,定义一个数组dim a(9),我们就可以理解了,a是一个物理地址的首地址,a里面的数据代表的是一个个偏移地址。
汇编语言的这种寻址方式([bx+idata]和[bx+si+idata]),为高级语言实现数组实现了便利机制。
既然是寻址,就要知道物理内存的地址。这个地址由两部分组成。段首地址和偏移地址。比方说,我有4个盒子,可以表示的信息量是2的四次幂,16个。我要有20个数据呢?怎么用四个盒子表示?就可以先用一种排列表示,然后再用一种排列表示,两种排列的顺序通过一定的约定,便可以表示20或者更多的数据了。
在计算机里的这一个约定是段首地址*16+偏移地址。
下面进入主题。
我们要把 BaSic和MinIx两个单词全部转化成大写字母。
在VB中,我们可以用Ucase函数,在C语言中常用的是每个字母的ASCII值减去32,在输出。
还有一种办法,通过把A,a,B,b等等的ascii二进制数写出来,找到一个规律。
大写字母和小写字母的二进制的区别是,大写字母第五位是0,小写是1。
所以在汇编语言中,我们利用的是逻辑and(与运算)和or(或运算)运算来实现大小写转换。
编写汇编代码
assume ds:data,cs:code
data segment
Db 'BaSic'
Db 'MinIx'
data ends
code segment
start:mov ax,data
Mov dx,ax
Mov bx,0
Mov cx,5
.注意下面的代码
s:Mov al,[bx]
And al,11011111
Mov [bx],al
Mov al,[bx+5]
Or al,00100000
Mov [bx+5],al
Inc bx
Loop s
._________________
mov ax,4c00h
int 21h
code ends
end start
程序段完了,那里的And al,11011111是为了把第五位的数组改成0,下面的同理。这里不是重点理解。
Mov al,[bx+5] 又可以写成 mov al,5[bx],Mov [bx+5],al 也可以写成mov 5[bx],al。是不是5[bx]这个和VB里面a()数组和C语言的a[]形式有点相似?如果还看不出来,我们用C语言写出中间那段程序。
Char a[5]="BaSic"
Char b[5]="MinIx"
main()
{
int i;
i=0;
Do
{
a[i]=a[i]&0xDF;
b[i]=b[i]|0x20;
i++;
}
While(i<5);
}
如果你熟悉C语言的话,可以比较这个C语言程序和上面汇编语言程序的相似之处。尤其注意它们定位字符串中字符的方式。
C语言:a[i],b[i]
汇编语言:0[bx],5[bx]
是不是可以看出什么。
当然,这还没有结束。
下面这个例子更为经典。
这是一个公司的数据:
公司名称:ABC
总裁名称:Abc Defgh
排名:100
收入:10亿
产品:LMN
这些都写在了内存里面。时隔几年后,数据有很多变了,我们要改变一些数据。比方说Abc Defgh的排名已经上升到38位,收入增加了70亿,产品变成了VAX系列计算机。
我们先用C语言写。
//下面先是定义,不做重点。
Struct company
{
Char cn[3];
Char hn[9];
Int pm;
Int sr;
Char cp[3];
}
Struct company dec{"ABC","Abc Defgh",100,10,"LMN"}
//下面是改数据的过程。
Main()
{
Int I;
Dec.pm=38;
Dec.sr=dec.sr+70
i=0;
Dec.cp='L';
i++;
Dec.cp='M';
i++;
Dec.cp='N';
Return 0;
}
用汇编语言写出改数据的部分就可以了。
Mov ax,seg
Mov ds,ax
Mov bx,60
.这里是重点
Mov word ptr [bx].0ch,38
Add word ptr [bx].0eh,70
Mov si,0
Mov byte ptr [bx].10[si],'L'
Inc si
Mov byte ptr [bx].10[si],'M'
Inc si
Mov byte ptr [bx].10[si],'N'
我们开始比较,C语言中的语句是Dec.cp='V',汇编语言中是.....[bx].10[si],'V'
在C语言中,我们看到,如: dec.cp[i],dec是一个变量名,指明了结构体变量的地址,cp是一个名称,指明了数据项cp的地址,而用i来定位cp中的每一个字符。汇编语言的做法是,bx.10[si]是不是很相似?
在熟悉的VB环境中,定义一个数组dim a(9),我们就可以理解了,a是一个物理地址的首地址,a里面的数据代表的是一个个偏移地址。
汇编语言的这种寻址方式([bx+idata]和[bx+si+idata]),为高级语言实现数组实现了便利机制。
相关文章推荐
- 通过两个汇编实例对高级语言数组实现原理的发现
- 通过两个汇编实例对高级语言数组实现原理的发现
- DropDownList通过数组方式实现两个DropDownList联动
- 通过汇编看vs2015下c++各标准库的实现原理
- Java基础---“接口”实现时的另一种方式。通过Java JDK API 1.6.0文档实例发现并得出结论
- 数组与Object的关系及其反射类型,数组反射应用实例,通过Array类实现数组的反射
- SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 SignalR 简单示例 通过三个DEMO学会SignalR的三种实现方式 SignalR推送框架两个项目永久连接通讯使用 SignalR 集线器简单实例2 用SignalR创建实时永久长连接异步网络应用程序
- 汇编语言编写数组的问题和实现输入两个十进制数输出的问题
- java实现把两个有序数组合并到一个数组的实例
- git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如: base'<--base<--A<--A' ^ | --- B<--B' 小米工程师常常需要寻找两个分支最近的分割点,即base.假设git 树是多叉树,请实现一个算法,计算git树上任意两点的最近分割点。 (假设git树节点数为n,用邻接矩阵的形式表示git树:字符串数组matrix包含n个字符串,每个字符串由字符'0
- 汇编语言学习——通过两个开关实现一个数码管的数字显示
- 递归神经网络LSTM原理——结合实例MATLAB实现
- 1.求第n个斐波那契数(非递归实现)。 2.一个数组中只有两个数字是出现一次,其他所有数字都出现 了两次。 找出这两个数字,编程实现。
- VB6 通过winsock控件数组实现客户端和服务器多对一通信
- (源码实例)通过层DIV实现,当鼠标放在链接上面,显示图片及文字
- 编程题:用一组数组做函数参数来实现,输入两个数,输出其中最大数
- C语言通过指针和数组实现字符串倒序
- php插入排序法实现数组排序实例
- 4-7 在一个数组中实现两个堆栈
- 通过单臂路由实现两个vlan的互访