assembly 第103行不是LDR编号而不是#0吗?

pcrecxhr  于 2023-10-19  发布在  其他
关注(0)|答案(2)|浏览(146)

screenshot of textbook(代码是将一系列数字相加并使用循环存储答案的示例)

100 LDM #0             ; Load 0 into ACC
101 STO total  
102 STO counter  
103 LDR #0             ; Load 0 into IX
104 loop:  
105 LDX number         ; Load the number indexed by IX into ACC
106 ADD total  
107 STO total  
108 INC IX  
109 LDD counter  
110 INC ACC  
111 STO counter  
112 CMP #3  
113 JPN loop  
114 END  
115 number: #5  
116 #7  
117 #3  
118 counter:  
119 total:

如果零存储在索引寄存器中,而不是定义“number”的地址,我不知道如何将预期的数字加载到累加器中。
如果第105行“LDX number”正在将地址加载到IX中,则旁边的注解“Load the number indexed by IX into ACC”会使我感到困惑。是否同时将地址加载到IX,并将此地址的号码加载到ACC?

bkhjykvo

bkhjykvo1#

是否同时将地址加载到IX,并将此地址的号码加载到ACC?
否:
它添加元素的地址(例如,变量)转换为IX中的值。
结果是一个地址。
CPU将该地址处的内存内容(加法之和)加载到寄存器ACC中。
换句话说:
如果寄存器IX包含值5,则指令加载第6个字(在大多数CPU上:字节)的变量number到寄存器ACC
如果你从IX=0开始,继续IX=1,依此类推,你首先加载number的第一个字,然后第二个字,依此类推.
第103行不是LDR编号而不是#0吗?
你也可以用下面的方式来做:

...
LDR # number
loop:
LDX 0
...

在这种情况下,IX已经包含了从哪里加载的“正确”地址,因此不需要在LDX指令中添加任何内容。
但是,下面的代码将工作:

...
LDR # number
loop:
LDX number
...

这段代码将从地址IX+number加载ACC。如果n是变量number的第一个字的地址,则代码将从2*n2*n+12*n+2.而不是nn+1等等.

zaqlnxep

zaqlnxep2#

在C语言中,它正在执行以下操作:

int counter = 0;
int total = 0;
int ix = 0;                    // initialize ix as an index, i.e. start at 0
do {
   total = total + number[ix]; // dereference array "number" at index ix
   ix++;
   counter++;
while ( counter < 3 );

或者,正如@Martin所说,我们可以使用指针来代替:

int counter = 0;
int total = 0;
int *ix = &number;       // initialize ix as pointer, i.e. to hold address of "number"
do {
   total = total + *ix;  // dereference pointer to fetch numbers
   ix++;
   counter++;
while ( counter < 3 );

在某些机器上,指针方法更短/更快,因为*ix没有第二个操作数,比number[ix]编码更短,更容易执行-这个片段在循环内部,所以(假设)重复执行。对ix进行更大的初始化是值得的,因为这是在循环之外,因此比较起来只发生一次。
混合使用这两种C方法是行不通的,在C中,你会从编译器中得到类型错误,这表明代码中存在逻辑错误。汇编不会提供这样的编译时错误,但将循环外的指针初始化与循环内的数组索引混合在一起仍然是逻辑错误。

相关问题