댓글 쓰기 권한이 없습니다. 로그인 하시겠습니까?
프로그램 카운터 관련 & 램 사용관련 질문 있습니다.
avrstudio 도움말을 보면
질문 1
PC <- PC + 1
과
PC <- PC + k + 1
이 있는데 여기서 k는 뭘 이야기 하는전지 잘 모르겠습니다.
질문 2
at89c51에서는 r레지스터가 3개(?? 3개가 맞나?)
on_off equ 60h
speed equ 61h
delay_l equ 62h
delay_h equ 63h
이런식으로 램을 사용했는데요
avr에서는 레지스터 외에는 사용할 수 없는 건가요?
질문 3
그리고 ro~r16
과
상위 r17~는 사용이 다른가요
데이타를 바로 쓰고 지욱고 하는데 차이점이 있는지요?
어떤 명령어를 실행하다 보면
레지스터의 사용이 안되는 부분이 있던데...
제가 잘못 알고 있는건지....
-
?
-
?
아.. 2번 질문에.. 어드레스 지시하는법을 질문하셨군요!
일단 .dseg랑 .org 지시어, .equ지시어에 대해 알아보세요.
.equ지시어는 님께서 알고계신 8051에 equ랑 같아요.
생각해보니, .db지시어, .dd지시어같은것도 8051에서도 db, dd이렇게 그대로 쓰이는군요.^^
아무튼..
아래처럼 하시면 될듯! 참고용입니다!~
.dseg
.org 0x0060
user_ram_a: .byte 1
user_ram_b: .byte 5
이렇게 하는게 있겠구요!
user_ram_a가 1바이트, b가 5바이트 예약되는겁니다!~
lds r0,user_ram_a
lds r2,user_ram_b+4
이런식으로 접근 됩니다.
님께서 하신 equ이 방법은
.equ user_ram_a = 0x0064(램 주소)
이렇게 가능하겠지만 AVR에선 보통은 이렇게 안해요!~
-
?


질문 1 : k가 의미하는것
k는 단지 상수입니다.
이것 역시 윤교수님 책에 자세히 서술되어 있습니다.
rcall, rjmp명령 사용할 때에는 상대값을 넣는데 그때 k에 값을 넣는거겠죠!~
질문 2 : AVR에서 램 사용
당연히 AVR에서도 램을 사용할 수 있습니다.^^ 램을 사용할 수 없다면 치명적이겠죠!!
램에서 데이터를 읽을 때에는
lds r16,주소
이렇게.. 램에 데이터를 쓸 때에는
sts 주소,r16
이렇게 합니다.
lds와, sts명령은 32비트로 용량을 많이 잡아먹죠..
그래서 여러번 램 값을 참조할 때에는
ldi zL,low(램 주소)
ldi zH,high(램 주소)
ldd r16,z+0
inc r16
std z+0,r16
ld r16,z+
st z,r16
이런식으로 사용하기도 합니다.
램에 접근하는 방법을 명령어로 정리하자면
lds, sts, ldd, std, ld, st
명령이 있습니다. 이것들을 잘 활용하시면 프로그램 용량이 확실히 줄어듭니다.
질문 3 : 레지스터 종류에 따른 차이
네! 차이가 있습니다.
r0~r15 : 즉치데이터 사용 불가능!
r16~r31 : 즉치데이터 사용 가능!
이 차이가 있습니다.
뭔 말이냐면..
r0~r15는
ldi, cpi, andi, ori, subi 명령을 사용할 수 없습니다.
이유는 명령어 뒤에 i가 immidiate(스펠링 잘 모름)로, 즉석, 즉치 데이터라는 뜻인데요.
이것을 사용할 수 없습니다.
왜 이렇게 해야 했는지는 잘 모르겠습니다.
참고로 ser명령또한 사용 불가능합니다. 기계어로 ldi r0,0xff 랑 같다고 생각하시면 되요. <-에러가 나지요
하지만, clr명령은 eor r0,r0 등으로 어셈블러가 자동 대체할 수 있기 때문에 가능합니다.^^
만약 이들 레지스터로 비교명령을 하려고 한다면
mov r16,r0
cpi r16
이런식으로 r16이상의 레지스터로 옮긴 후 비교합니다.
즉치 데이터 로드할 때에도
ldi r16,0x01
mov r0,r16
이렇게요
참고로 눈치가 있는분은 아시겠지만...
clr r0
inc r0
이렇게 해도 1을 얻을 수 있습니다.
다른 레지스터를 건들면 곤란한 상황이 생길 수 있는데(특히 인터럽트 처리 등 레지스터 사용이 제한적일 때), 이 때 r0자체적으로 0,1,255정도의 값은 명령 2개 내로 얻을 수 있지요.
r16~r31은 즉치데이터 사용 가능하지요!
따라서 andi, ori, ser, ldi, cpi명령이 사용 가능하지요.
다만 이것들이 다 똑같다 생각하시면 안되요!
lpm이나 elpm명령은 r30,r31의 조합(z레지스터라 하지요)으로 구동되고...
ld rd,z+
ld rd,-z
st z+,rd
st -z,rd
이런 명령은 z, y레지스터라 불려지는 r31,r30,r29,r28에서만 가능하고
x레지스터 r27,r26은..
ld rd,z
st z,rd
만 가능하죠
ldd std에서도 x레지스터에서는 불가능할겁니다.
16비트 뺄샘 명령인 sbiw는 아마 다 되나 모르겠는데,
16비트 덧셈 명령인 adiw는 아마 x,y,z레지스터에서만 가능할겁니다.^^