It is currently Sun Dec 17, 2017 4:34 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Fri Oct 02, 2009 2:39 am 
Offline
User avatar

Joined: Sun Feb 15, 2009 8:23 am
Posts: 27
引用http://nicotine.knight.blog.163.com/blog/static/2692611220099251548925/
好多人都是先会高级语言再说汇编的。在学汇编时,学到寻址就搞不明白。

我现在拿CPU6502(就是任天堂红白机用的CPU)来说说寻址与高级代码的关系。



6502资料可以看"图解6502 指令集.pdf"或"6502编程大奥秘.chm(前三章节就够)"。我个人比较喜欢看后者。

下载http://www.uushare.com/user/fogota/files/1648814 或 http://www.uushare.com/user/lzwcsj/files/1009423



6502的寻址有13个。

1。立即寻址

就是一个数(只有一个字节,即8位)直接存放在指令的后面。指令就直接调用这个数值。

例子:

LDA #03 //就是将03传入A寄存器。

STA W //W为一个变量,这里用了“直接寻址”,下面有说明,这一行的作用是将A寄存器的值传到W上。

高级代码 为 W=3;



2。直接寻址

就是一个地址存放在指令的后面。指令就通过这地址调用该地址上的数值。

2.1

例子:

LDA #03

STA W //W为一个变量,W也是一个地址。高级代码不直接写地址而是写成变量。

高级代码 为 W=3;

2.2

如果 W地址就是$0300

那么STA W 写成纯汇编就是 STA $0300

2.3

LDA #03

STA $0300

就是将03这个数值先传到A寄存器,再通过A传到内存地址$0300。CPU是不能直接将数值传到内存上的。

2.4

例如:有2个变量N和W

N=W

写汇编就是

LDA W

STA N



3。零页寻址

这个是6502所特有的,它就是局限在零页,省了高位的数据,用法与"直接寻址"完全相同。



4。累加器寻址

它是说从寄存器A上取值。我可以找到"位移操作"。

位移,例如

LDA W

ASL //操作数就在A中

STA N

写成高级代码

N = W << 1



5。隐含寻址

这个与累加器寻址相近,唯一不同就是它在除寄存器A外的寄存器上取值。在调用子函数或递返时用作入栈出栈。



零页寻址,累加器寻址,隐含寻址这三个都没有可说的,它们与高级代码没有可比较的。



6。直接X变址

这就是拿给出的地址作为基础,并偏移X个量,到达的地址就是所要的。

这个跟数组的使用一样

6.1

例如:一个数组W,它的首地址就是W,即W的第一个元素W(0)的地址就是W

LDX #03

LDA W,X

STA N

高级代码 N=W(3);

6.2

在纯汇编中是不用变量的,如果W地址就是$0300

那么

LDX #03

LDA $0300,X

STA $0200

就是向地址$0200写入在地址$0303上的值

等同

LDA $0303

STA $0200



7。直接Y变址

用法跟“直接X变址”完全相同,一般是X已被占用。才用这个的。



8。零页X变址,这个与“直接X变址”相近,就是局限在零页,省略高位。



9。零页Y变址,这个与“直接Y变址”相近,就是局限在零页,省略高位。



直接Y变址,零页X变址,零页Y变址这三个,只要理解“直接Y变址”就能学会。



10。间接寻址

就是指令后面放了一个指针的地址。

这就好理解了。

例如:P是一个指针,它是由2个字节组成的。地址为P和P+1

JMP (P) //这个不是跳到P地址上,而是跳到P所指向的地址。

这个要说明一下机器码。地址$0300写成机器码是00 03,高低位是反放的。

那么P+1是高位,P是低位。

如果P地址上的值是00 ,P+1地址上的值03

那么JMP (P) 等同 JMP $0300

高级代码绝少这样用,一般是编译器用的。JMP (P) 勉强写成 goto *p



11。先变址X后间接寻址

这样理解"先X变址,之后再间接寻址"

简单说就是分两步做

第一步是先做上面"6。直接X变址"

第二步是做"10。间接寻址"。

理解为一个指针数组

例如:P为一个由指针构成的数组。

ldx #03

lda (P,X)

sta W

写成高级代码

W=*P(3)



12。先间址后变址Y

这样理解"先间接寻址,之后再Y变址"

简单说就是分两步做

第一步是先做上面"10。间接寻址"

第二步是做"7。直接Y变址"。

理解为一个指针,指向一个数组(的首地址)。

例如,一个数组W。W也是数组的首地址,即W(0)的地址

P记录着这个数组的首地址。即P=&W

ldy #03

lda (P),Y

sta N

写成高级代码是

P=&W

...

N=*P(3)



13。相对寻址

这个就是专用在条件跳转上的。意思是相对当前所在地址向前或向后跳一个指定的偏移量。

高级代码中一般不用,而是在代码结构里用上了,是编译器最终写定的。

例如

while....

{...

}

这个while为假时就是要跳过}的,这个是由编译器计算跳多远。

又例如

if .... then ... else ....

这个else就是要跳过then后面的代码,相对多远,编译器计算,then结束后又要跳过else部分,同相。









Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group