[原创教程] 汇编寻址与高级代码的对应关系

Chinese-language board. 为NES/FC开发商的中国语言论坛 | 為NES/FC開發商的中國語言論壇

Moderator: Moderators

Post Reply
User avatar
fogota
Posts: 27
Joined: Sun Feb 15, 2009 8:23 am
Contact:

[原创教程] 汇编寻址与高级代码的对应关系

Post by fogota »

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

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



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

下载http://www.uushare.com/user/fogota/files/1648814http://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部分,同相。







Post Reply