利用 Ophis 编写 Commodore 64 programs PRG 程序(五)

本文介绍了汇编语言中分支、循环的基本结构,包括if-else、while、for循环的实现,并展示了如何使用栈来保存状态。在汇编中,分支通常依赖于特定的条件跳转指令,如bne、beq等。循环通过调整零页内存或寄存器来控制,而栈则利用内存的第一页进行操作,用于子程序调用和保护寄存器状态。
摘要由CSDN通过智能技术生成

上一节中,我们理解了表达式和零页,接下来让我们一起来看看一些汇编代码与高级语言的对应关系:分支、循环与栈
本节参考了Structured ProgrammingThe stackProcedures and register saving

分支语句if else

汇编语言一般使用相反的构造方式,即将if块中的代码紧跟在分支判断之后,若if条件成立则什么都不做,若不成立则直接跳过该块语句。
分支语句一般使用bcc/bcs/beq/bmi/bne/bpl/bvc/bvs做各种标志位的判断。

  • 仅有if
if(!++y) x++;
   iny
   bne no'overflow
   inx
no'overflow:
   ;; rest of code
  • 同时有if else
if(前一个运算相等) {
	//Then
} else {
	//Else
}
   ;; Computation of the conditional expression.
   ;; We assume for the sake of the example that
   ;; we want to execute the THEN clause if the
   ;; zero bit is set, otherwise the ELSE
   ;; clause.  This will happen after a CMP,
   ;; which is the most common kind of 'if'
   ;; statement anyway.

   BNE else'clause

   ;; THEN clause code goes here.

   JMP end'of'if'stmt
else'clause:

   ;; ELSE clause code goes here.

end'of'if'stmt:
   ;; ... rest of code.

循环语句

1. while循环

  • while
while(前一次比较不相等) {
	//Loop
}
loop'begin:
   ;; ... computation of condition, setting zero
   ;;     bit if loop is finished...
   beq loop'done
   ;; ... loop body goes here
   jmp loop'begin
loop'done:
   ;; ... rest of program.
  • do while
do {
	//Loop
} while(前一次比较不相等);
loop'begin:
   ;; ... loop body goes here
   ;; ... computation of condition, setting zero
   ;;     bit if loop is finished...
   bne loop'begin
   ;; ... rest of program.

2. for循环

下面的程序实现16字节的内存拷贝。为了简化代码,x实际上从16递减到1,于是内存地址也进行了相应平移。

int *a = 0xC000;
int *b = 0xD000;
for (int x = 0; x < 16; x++) { a[x] = b[x]; }
   ldx #$10		; 16进制16
loop:
   lda #$bfff, x
   sta #$cfff, x
   dex
   bne loop

3. 嵌套循环

由于寄存器只有8位,使得C64汇编的嵌套循环非常简单。因为不管是递增还是递减,寄存器总会回到0,此时就是循环退出的时机。不过,由于可以递增/递减的寄存器只有2个,因此两层以上的嵌套循环需要用到内存。为了不使内存读写拖慢运行速度,可以使用上一节提到的零页内存进行计数。当然,在循环中的代码会破坏xy寄存器时,也可以使用内存进行循环计数。
在与C64同芯片的NES中,显示器IO的内存地址位于0x2007 ,因此我们可以使用如下代码向其中写入40960x20

   ldx #$10
   ldy #$00
   lda #$20
loop:
   sta $2007
   iny
   bne loop
   dex
   bne loop

栈位于内存的第1页。可以通过txs指令修改栈指针,指针指向0xFF表示栈为空。调用子程序的jsr指令会将当前指令地址入栈,返回的rts指令则会将出栈的地址加一后跳转到该处执行。中断时也会使用该栈。
当然,因为一页内存只有256字节,因此递归调用会很容易溢出。
因此,一个类似C语言的函数应该如下。函数在开始时保护所有寄存器,在结束时恢复。

do'stuff:
   pha
   txa
   pha
   tya
   pha

   ;; Rest of do'stuff goes here

   pla
   tay
   pla
   tax
   pla
   rts
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值