Assembly Language
스택
수색…
비고
컴퓨터 스택은 여러 권의 책과 같습니다. PUSH 는 상단에 하나를 추가하고 POP 는 맨 위를 벗어납니다. 실생활 에서처럼 스택은 끝이 없으므로 최대 크기를 갖습니다. 스택은 다른 알고리즘을 수행하는 동안 정렬 알고리즘, 더 많은 양의 데이터 또는 레지스터의 안전한 값을 처리하는 데 사용할 수 있습니다.
Zilog Z80 Stack
레지스터 sp
는 마지막으로 저장된 값 (스택의 "최상위")을 가리키는 스택 포인터 로 사용됩니다. 따라서 EX (sp),hl
은 hl
의 값을 스택 맨 위에있는 값과 교환합니다.
"상부"단어는 달리, 스택은 감소시킴으로써 메모리에 성장 sp
하고 늘려 자료 ( "팝") 값 sp
.
sp
= $4844
경우 값 1
, 2
, 3
이 스택에 저장됩니다 ( 3
이 마지막 값으로 스택에 푸시 됨으로써 맨 위에 표시됨). 메모리는 다음과 같습니다.
| address | value bytes | comment (btw, all numbers are in hexadecimal)
| ---------- | ----------- | ---------------------------------
| 4840 | ?? ?? | free stack spaces to be used by next push/call
| 4842 | ?? ?? | or by interrupt call! (don't expect values to stay here)
| sp -> 4844 | 03 00 | 16 bit value "3" on top of stack
| 4846 | 02 00 | 16 bit value "2"
| 4848 | 01 00 | 16 bit value "1"
| 484A | ?? ?? | Other values in stack (up to it's origin)
| 484C | ?? ?? | like for example return address for RET instruction
스택을 사용한 명령어의 예 :
LD hl,$0506
EX (sp),hl ; $0003 into hl, "06 05" bytes at $4844
POP bc ; like: LD c,(sp); INC sp; LD b,(sp); INC sp
; so bc is now $0506, and sp is $4846
XOR a ; a = 0, sets zero and parity flags
PUSH af ; like: DEC sp; LD (sp),a; DEC sp; LD (sp),f
; so at $4844 is $0044 (44 = z+p flags), sp is $4844
CALL $8000 ; sp is $4842, with address of next ins at top of stack
; pc = $8000 (jumping to sub-routine)
; after RET will return here, the sp will be $4844 again
LD (L1+1),sp ; stores current sp into LD sp,nn instruction (self modification)
DEC sp ; sp is $4843
L1 LD sp,$1234 ; restores sp to $4844 ($1234 was modified)
POP de ; de = $0044, sp = $4846
POP ix ; ix = $0002, sp = $4848
...
...
ORG $8000
RET ; LD pc,(sp); INC sp; INC sp
; jumps to address at top of stack, "returning" to caller
요약 : PUSH
는 스택의 맨 위에 값을 저장하고 POP
는 스택의 맨 위에서 값을 가져옵니다. LIFO (마지막에서 처음으로) 대기열입니다. CALL
은 JP
와 동일하지만 스택 맨 위에 CALL
후 다음 명령어의 주소를 푸시합니다. RET
은 JP
와 비슷하며 스택에서 주소를 팝핑하고 점프합니다.
경고 : 인터럽트가 활성화되면 인터럽트 신호가 처리기 루틴을 호출하기 전에 반환 주소 (실제 pc
)를 저장하므로 인터럽트 신호 중에 sp
가 유효해야하며 인터럽트 처리기 루틴을 위해 충분한 여유 공간이 예약되어 있어야합니다. 스택. 인터럽트가 발생하면 sp
보다 앞서 모든 값이 "예기치 않게"수정 될 수 있습니다.
고급 기법 : PUSH
가 11 클럭 사이클 (11t)을 취하고 POP
가 10t 인 경우 그림자 변형에 대한 EXX
를 포함하여 펼쳐진 POP
/ PUSH
Trough의 모든 레지스터가 압축 해제 된 LDI
보다 훨씬 빠른 메모리 블록을 복사하는 가장 빠른 방법이었습니다. 하지만 메모리 손상을 피하기 위해 인터럽트 신호 사이의 복사본을 준비해야했습니다. 또한 PUSH
를 풀면 ZX Spectrum의 특정 값으로 메모리를 채우는 가장 빠른 방법이었습니다 (정상적으로 시간을 정하지 못했거나 DI
수행 한 경우 Interrupt에 의한 손상 위험이 있음).