Assembly 如何使用1寻址模式在程序集中通过加载添加两个存储值?
我想添加存储的两个值x和y,但我只想使用1寻址模式。Assembly 如何使用1寻址模式在程序集中通过加载添加两个存储值?,assembly,6502,Assembly,6502,我想添加存储的两个值x和y,但我只想使用1寻址模式。 以下是一个例子: lda x sta x // store the final result in x lda y sta y // store the final result in y //now I want to add x and y like x+y. Is the following pattern correct? whats wrong? lda x lda y add x sta x 6502上的添加仅在蓄能器中
以下是一个例子:
lda x
sta x
// store the final result in x
lda y
sta y
// store the final result in y
//now I want to add x and y like x+y. Is the following pattern correct? whats wrong?
lda x
lda y
add x
sta x
6502上的添加仅在蓄能器中完成
- 加载累加器中的第一个数字
- 将第二个数字添加到累加器中
- 将累加器存储在内存中
lda x ;This is useless
lda y
add x
sta x
同样,6502指令集中没有add
指令,也没有sub
指令。不过,我愿意让您放心,因为定义几个宏完全可以避免每次开始新的加法或减法时都必须编写clc
和sec
使用现代FASM语法添加的示例:
macro add op
{
clc
adc op
}
使用非常旧的METACOMCO语法的sub
示例:
sub MACRO
sec
sbc \1
ENDM
如果这应该是6502代码,那么加法的操作码是
adc
,意思是“带进位的加法”。如果没有进位,则没有添加操作
lda
用一个值加载累加器,因此两个直接顺序的lda
是完全无用的。只需使用一个lda
,后跟一个adc
(这将向累加器添加任何地址,并添加进位标志)
总而言之,序列看起来很简单:
lda x
adc y
sta x
例如,x
和y
可以是绝对地址
但是要注意携带标志!如果您无法了解进位状态,则需要先执行clc
(清除进位)指令。如果您知道将设置进位,并且y
是一个立即值,只需少加一个即可。如果你不能做到这一点,你还需要一个clc
一般来说,总是尽量避免使用clc
(它需要一个字节和一些周期,这在如此有限的芯片上确实很重要),但有时您会需要它
可避免
clc
(实现的一部分)的真实代码示例:
需要clc
(实现的一部分)的真实代码示例:
下面的模式正确吗?怎么了
没有
- 添加操作始终使用蓄能器完成
- 没有
指令,只有ADD
addwithcarryADC
- 您需要管理进位标志
; x = x + y
LDA x ; Load one operand into the accumulator.
CLC ; Clear the carry flag so it does not get added into the result
ADC y ; Add the other operand
STA x ; Store the operand back to x
您可以对y使用任何地址模式,对x使用任何地址模式,即时除外
如果x和y是16位值的地址,则16位加法如下所示:
LDA x ; Load one operand into the accumulator.
CLC ; Clear the carry flag so it does not get added into the result
ADC y ; Add the other operand
STA x ; Store the operand back to x
LDA x+1 ; Now do the high byte
ADC y+1 ; Note we do not clear the carry this time.
STA x+1
这不是x86,请使用正确的体系结构标记。无论如何,
lda x
之后的lda y
将覆盖加载的值。您只需加载x
,然后添加y
。容易的。也就是说,您的代码应该可以工作,但是没有必要使用lda x。y在添加之前未加载。lda x;加y;sta结果
。或者,lday;加x;sta结果
。请将此答案添加到回答框中,以便我可以接受。6502缺少直接添加,您需要一个CLC+ADC
序列。然后再次给出原始代码和ISA属性,这很可能是6800代码。中没有ADD
指令6502@JeremyP你能同意在6502号上,定义add
和sub
宏是有意义的,以避免必须编写clc
和sec
?是的,您可以创建这些宏,我看不出有任何理由不这样做,但我从未见过这样做。在进行新添加时,您无法避免使用clc
(与多字节数的高阶字节相反),除非您已经知道进位标志的状态。@JeremyP这是我写的?您写道“一般来说,总是尽量避免clc
”然而,事实上,它或多或少应该是自动放入的。@JeremyP您应该阅读整个答案,我首先解释了何时/如何避免它。在6502上,冗余的clc
是不好的做法。@JeremyP这是错误的。您通常知道标志的状态。代码片段直接跳转到添加标志的位置有些东西只是你完全忘记了你的代码的标志。6502上的每个字节和每个周期都是宝贵的。
nts_addloop: lda nc_string,x
cmp #$5 ; value >= 5 ?
bcc nts_noadd ; after not branching here, we know C=1
adc #$2 ; then add 3 (2 + carry)
sta nc_string,x
nts_noadd: dex
mul_rorloop: ror mpm_arg1,x
dex
bpl mul_rorloop
bcc mul_noadd ; we know carry is set when not branching
ldx #($80-NUMSIZE)
clc ; clear it because we have to add a variable value
mul_addloop: lda mpm_arg2+NUMSIZE-$80,x
adc mpm_res+NUMSIZE-$80,x
sta mpm_res+NUMSIZE-$80,x
inx
bpl mul_addloop
mul_noadd: ldx #($81-NUMSIZE)
; x = x + y
LDA x ; Load one operand into the accumulator.
CLC ; Clear the carry flag so it does not get added into the result
ADC y ; Add the other operand
STA x ; Store the operand back to x
LDA x ; Load one operand into the accumulator.
CLC ; Clear the carry flag so it does not get added into the result
ADC y ; Add the other operand
STA x ; Store the operand back to x
LDA x+1 ; Now do the high byte
ADC y+1 ; Note we do not clear the carry this time.
STA x+1