S3C64XX 부팅 코드 부분에 어셈블리어를
잠깐 제어할 일이 생겼었다.
막상 제어를 하다보면 r1 값에 0x453fff60 이란 32bit 값을 넣어야 되는데
그부분에 막혔다.
mov r1, #0x453fff60 이 구문이다.
에러 메시지는
invalid constant (0x453fff60) after fixup
이런 메시지.. 구글링으로 검색해본 결과
mov r1, #0x4500000000
orr r1, r1, #0x3f000000
orr r1, r1, #0xff0000
orr r1, r1, #0xff00
orr r1, r1 #0x60
이런식으로 넣어줘야 되는것이다
이유인즉슨
AMR7은 32 Bit 코어입니다. 특징적인 것은 모든 명령어가 32Bit 하나의 Word로 구성된 다는 것입니다. 8086의 경우엔 명령어에 따라 1바이트 명령부터 5바이트까지 있나요? 그런 데, ARM7은 모든 명령어를 한 워드 (32bits) (주;Thumb 모드시는 16bits) 로 처리합니다. 일단은 명령어의 개수가 몇 안되고, 주 소는 상대주소 방식을 사용하며, 심지어는 Immediate 상수 값도 32비트 값은 그대로 넣을 수 없습니다. 무슨 이야기인가 하면, 만약 r0에 32비트 상수를 넣고 싶다면, 몇몇 예외를 제외하고는 메모리에 미리 넣어두고 해당 메모리를 상대 주소로 참조해서 얻어 와야 한다는 뜻입니다. 역시 장단점이 있겠지만, 장점으로는 모든 명령어를 같은 사이즈로 처리함에 따라 파이프 라인 구현이 용이하다는 점이 있습니다. 그리고 명령어 해석기를 설계할 경우 예외 처리부 분이 없으므로, 쉽고 고속으로 처리할 수 있겠지요. 단점은 앞에서도 간단히 언급했지만 코딩 시에 몇몇 제한이 따른다는 점입니다. 상대 주소 지정 방식은, 이때 사용하는 Offset이 24+2=26 비트이므로, 상대주소라고는 하지만 거의 불편이 없고, 다만 Immediate 오퍼랜 드를 지정할 경우에 좀 번거롭다는 점이 있습니다. 그러나 8비트의 해상도를 가지는 오퍼랜드라면 한 워드 내에서 처리 가능합니다. --- ARM assembler는 위와 같이 8bit가 넘어가는 오퍼랜드를 매번 위와 같이 코딩하는 것이 귀찮은 사람들 (저같은 ;-) 을 위해 LDR pseudo instruction을 제공합니다. 만약 위와 같이 코딩하는 것이 귀찮다면, LDR pseudo intstruction 을 이용하여 다음과 같이 코딩하시면 됩니다. (두번째 오퍼랜드 앞에 '=' 주의 ) ONENAND EQU 0x20c3c800 ... LDR r0, =ONENAND ... ARM assembler referece 북에 의하면 오퍼랜드가 8비트로 표현이 되면, 위의 표현식은 MOV 나 MVN으로 바꾸고, 8bit가 넘어가면 상수값을 literal pool을 생성하여 저장한 후, 이 literal pool에서 PC-relative LDR로 읽어오는 형태로 바꿔준다고 합니다. 저도 가끔은 왜 사람들이 이 슈더 인스트럭션을 안쓰고, 굳이 저렇게 두가닥, 세가닥, 혹은 극한 경우 네가닥 으로 나누어서 코딩하나 궁금한 적이 있었는데..., 혹시 위처럼 하면 전체 메모리를 덜 잡아먹나 (코드 메모리는 더 쓰지만, 리터럴 풀이 필요없으니까..) ? 아님, 명령셋이 pipeline에서 기다리지 않아도 되니까 빠른 코드가 나오게 되나 ? 그렇게 짐작만할 뿐, 정확한 이유는 모르겠더라구요.
출처 : http://www.aesop.or.kr/?mid=Board_QA_S3C64X0&listStyle=gallery&page=19&document_srl=38535&SSOID=330005a7894ab103275d94658137cc33
이솝 커뮤니티
대충 이야기가 32bit adress 를 한방에 억세스 안되게끔 한건데 이게 꼭 단점이 될수는 없다
왜냐면 32bit operand 를 포기하고 대신 빠르고 저전력인 심플한 core 를 만들었다는게.. 위의 글의 촛점인거 같다 ㅎ
대학교 2학년에 배운 컴퓨터구조에 RISC 구조가 실전에서 이렇게 쓰일줄이야..
감탄할 따름이다 ㅎ
알기위해 더욱더 노력해야겠다 ㅋㅋ

잠깐 제어할 일이 생겼었다.
막상 제어를 하다보면 r1 값에 0x453fff60 이란 32bit 값을 넣어야 되는데
그부분에 막혔다.
mov r1, #0x453fff60 이 구문이다.
에러 메시지는
invalid constant (0x453fff60) after fixup
이런 메시지.. 구글링으로 검색해본 결과
mov r1, #0x4500000000
orr r1, r1, #0x3f000000
orr r1, r1, #0xff0000
orr r1, r1, #0xff00
orr r1, r1 #0x60
이런식으로 넣어줘야 되는것이다
이유인즉슨
AMR7은 32 Bit 코어입니다. 특징적인 것은 모든 명령어가 32Bit 하나의 Word로 구성된 다는 것입니다. 8086의 경우엔 명령어에 따라 1바이트 명령부터 5바이트까지 있나요? 그런 데, ARM7은 모든 명령어를 한 워드 (32bits) (주;Thumb 모드시는 16bits) 로 처리합니다. 일단은 명령어의 개수가 몇 안되고, 주 소는 상대주소 방식을 사용하며, 심지어는 Immediate 상수 값도 32비트 값은 그대로 넣을 수 없습니다. 무슨 이야기인가 하면, 만약 r0에 32비트 상수를 넣고 싶다면, 몇몇 예외를 제외하고는 메모리에 미리 넣어두고 해당 메모리를 상대 주소로 참조해서 얻어 와야 한다는 뜻입니다. 역시 장단점이 있겠지만, 장점으로는 모든 명령어를 같은 사이즈로 처리함에 따라 파이프 라인 구현이 용이하다는 점이 있습니다. 그리고 명령어 해석기를 설계할 경우 예외 처리부 분이 없으므로, 쉽고 고속으로 처리할 수 있겠지요. 단점은 앞에서도 간단히 언급했지만 코딩 시에 몇몇 제한이 따른다는 점입니다. 상대 주소 지정 방식은, 이때 사용하는 Offset이 24+2=26 비트이므로, 상대주소라고는 하지만 거의 불편이 없고, 다만 Immediate 오퍼랜 드를 지정할 경우에 좀 번거롭다는 점이 있습니다. 그러나 8비트의 해상도를 가지는 오퍼랜드라면 한 워드 내에서 처리 가능합니다. --- ARM assembler는 위와 같이 8bit가 넘어가는 오퍼랜드를 매번 위와 같이 코딩하는 것이 귀찮은 사람들 (저같은 ;-) 을 위해 LDR pseudo instruction을 제공합니다. 만약 위와 같이 코딩하는 것이 귀찮다면, LDR pseudo intstruction 을 이용하여 다음과 같이 코딩하시면 됩니다. (두번째 오퍼랜드 앞에 '=' 주의 ) ONENAND EQU 0x20c3c800 ... LDR r0, =ONENAND ... ARM assembler referece 북에 의하면 오퍼랜드가 8비트로 표현이 되면, 위의 표현식은 MOV 나 MVN으로 바꾸고, 8bit가 넘어가면 상수값을 literal pool을 생성하여 저장한 후, 이 literal pool에서 PC-relative LDR로 읽어오는 형태로 바꿔준다고 합니다. 저도 가끔은 왜 사람들이 이 슈더 인스트럭션을 안쓰고, 굳이 저렇게 두가닥, 세가닥, 혹은 극한 경우 네가닥 으로 나누어서 코딩하나 궁금한 적이 있었는데..., 혹시 위처럼 하면 전체 메모리를 덜 잡아먹나 (코드 메모리는 더 쓰지만, 리터럴 풀이 필요없으니까..) ? 아님, 명령셋이 pipeline에서 기다리지 않아도 되니까 빠른 코드가 나오게 되나 ? 그렇게 짐작만할 뿐, 정확한 이유는 모르겠더라구요.
출처 : http://www.aesop.or.kr/?mid=Board_QA_S3C64X0&listStyle=gallery&page=19&document_srl=38535&SSOID=330005a7894ab103275d94658137cc33
이솝 커뮤니티
대충 이야기가 32bit adress 를 한방에 억세스 안되게끔 한건데 이게 꼭 단점이 될수는 없다
왜냐면 32bit operand 를 포기하고 대신 빠르고 저전력인 심플한 core 를 만들었다는게.. 위의 글의 촛점인거 같다 ㅎ
대학교 2학년에 배운 컴퓨터구조에 RISC 구조가 실전에서 이렇게 쓰일줄이야..
감탄할 따름이다 ㅎ
알기위해 더욱더 노력해야겠다 ㅋㅋ