Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 管理参数和返回地址时处理堆栈的正确约定_Assembly_68hc12 - Fatal编程技术网

Assembly 管理参数和返回地址时处理堆栈的正确约定

Assembly 管理参数和返回地址时处理堆栈的正确约定,assembly,68hc12,Assembly,68hc12,当您需要访问堆栈中“位于”其下方的参数时,将调用函数的返回地址置于堆栈中任何参数之上的最佳方法是什么?我使用的是S12摩托罗拉/飞思卡尔处理器。S12具有16位的:D寄存器,包括A和B寄存器,每个寄存器具有8位。X和Y索引寄存器每个16位、一个程序计数器和一个堆栈指针。代码示例为: MAIN ORG $1500 ;Set the start of the program LDD #SomeValue ;Load the D register with a

当您需要访问堆栈中“位于”其下方的参数时,将调用函数的返回地址置于堆栈中任何参数之上的最佳方法是什么?我使用的是S12摩托罗拉/飞思卡尔处理器。S12具有16位的:D寄存器,包括A和B寄存器,每个寄存器具有8位。X和Y索引寄存器每个16位、一个程序计数器和一个堆栈指针。代码示例为:

MAIN ORG    $1500        ;Set the start of the program 
     LDD    #SomeValue   ;Load the D register with a value
     PSHD                ;Push D onto the stack
     JSR    ROUTINE      ;Go to the subroutine - pushes the PC to the SP
END_MAIN    END

ROUTINE     
     PULD                ;Pull the top of the stack into the D register
                         ;D now holds the address for returning to the 
                         ;main function. 
     PSHD                ;Push the return address back onto the stack
END_ROUTINE RTS          ;Return to Main routine
问题是堆栈的顶部保存着下一条指令的地址,这使得它很难绕过。例如,如果我需要一个位于地址下面的参数,我必须手动调整SP,这看起来很粗糙,或者我必须将堆栈的顶部拔出,并将其存储在占用空间的寄存器中。最后一种方法的一个转折点是将返回地址存储在变量中,不幸的是,这里声明的变量在作用域中是全局的,这并不理想

ReturnAddress EQU $2000        ;Declare variable at address $2000
STD           ReturnAddress    ;Store the D register's contents in variable

还有其他我在这里没有看到的选择吗

由于Jester的一些输入,能够观察堆栈中发生的事情并使用其中包含的参数是相当简单的。我编写了一个简单的程序,演示如何通过值和引用传递参数

QUOTIENT    EQU     $1000       ;Variable to hold our QUOTIENT
REMAINDER   EQU     $1002       ;Variable to hold our REMAINDER

MAIN        ORG     $2000       ;Set the start of the program
            LDD     #!50        ;Load the D register with a value (16 bits)
            PSHD                ;Push D onto the stack (16 bits)
            LDD     #!10        ;Load the D register with a value (16 bits)
            PSHD                ;Push D onto the stack (16 bits)
            LDD     #QUOTIENT   ;Load the D register with an address (16 bits)
            PSHD                ;Push D onto the stack (16 bits)
            LDD     #REMAINDER  ;Load the D register with an address (16 bits)
            PSHD                ;Push D onto the stack (16 bits)
            JSR     DIVIDE      ;Push the PC onto the stack (16 bits).
            LEAS $0A, SP         ;Instead of PULD 5x, thanks Jester
END_MAIN    END


;******************************************************************************;
;DIVIDE - This routine expects the following parameters to be on the stack:
; STACK
;( 0 ) - (16 bits for return address)
;( 2 ) - (16 bits of address to store the REMAINDER (ANSWER var reference))
;( 4 ) - (16 bits of address to store the QUOTIENT (ANSWER var reference))
;( 6 ) - (16 bits for divisor)
;( 8 ) - (16 bits for dividend)
;******************************************************************************;
DIVIDE      LDD     8,SP       ;Loads the dividend (50)
            LDX     6,SP       ;Loads the divisor (10)
            IDIV               ;Divide
            LDY     4,SP       ;Get the address of the Quotient
            STX     0,Y        ;Store at that address
            LDY     2,SP       ;Get the address of the remainder
            STD     0,Y        ;Store at that address
END_DIVIDE  RTS

使用其他架构的诀窍是访问相对于堆栈指针的堆栈,您有这样的寻址模式吗?快速谷歌搜索说是的,你可以做一些类似LDAA4,SP的事情。如果我理解你的要求,我想是的。为了做到这一点,我认为堆栈必须首先加载到一个索引寄存器中。在这种情况下进行编辑,是否可以访问子例程中所需的参数,然后在恢复原始例程后将其从堆栈中弹出?请参阅您的手册,我在谷歌上明确指出您可以使用SP.Cheers,我刚刚在学习组装,我想我很难清楚地说出我到底在寻找什么。所以RTFM并不是我的解决方案。请注意,您通常通过调整堆栈指针来丢弃堆栈中的项。五个PULD说明通常写为LEAS 10,SP。感谢您的建议!