2016-08-26 3 views
0

현재 사용자 정의 asm과 같은 프로그래밍 언어 용 컴파일러를 작성하고 있으며 데이터 레이블에 적절한 PC 상대 주소 지정을 수행하는 방법에 대해 혼란스러워합니다.어셈블리와 유사한 언어 컴파일러에서 PC 상대 주소 지정

main LDA RA hello 
     IPT #32 
     HLT 

hello .STR "Hello, world!" 

위의 의사 코드는 컴파일 후, 다음의 진수 결과 :

31 80 F0 20 F0 0C 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 00 

3180, F020F00CLDA, IPTHLT 지침입니다.

코드에서 볼 수 있듯이 LDA 명령어는 hello 레이블을 인수로 사용합니다. 컴파일 할 때 02이라는 값이됩니다. 이는 "Incremented PC + 0x02"를 의미합니다 (코드를 보면 LDA 호출과 관련하여 "Hello, world!"행의 위치입니다.) 문제는 다음과 같습니다. .STR은 명령어가 아니며 컴파일러에게 실행 파일 끝에 (0 종료 된) 문자열을 추가해야한다는 것을 알려주기 때문에 hello 라벨 선언 다음에 다른 명령어가 있었으므로 그 오프셋은 잘못되었습니다.

하지만 올바른 방법으로 오프셋을 계산할 수있는 방법을 찾지 못했습니다. 컴파일러가 시간을 거슬러 올라갈 수있는 것 외에는 두 번 컴파일해야합니까? 처음에는 데이터 레이블, 실제 지침 ?

+1

'hello'의 선언에 대한 오프셋은'.STR' 변수 다음에 오는 명령어에 의해 변경되지 않습니다. – kdopen

답변

2

예, 대부분의 어셈블러는 (적어도) 2 회 통과합니다. 정확하게 이와 같은 전방 참조가 있기 때문입니다. 매크로 기능을 추가하면 패스를 추가 할 수 있습니다.

op 코드가 아닌 어셈블리 목록을보십시오. 실제 오프셋이 "2"라고 했으므로 메모리가 단어로 주소가 지정된 것으로 가정합니다.

0000 3180 main LDA RA hello 
0001 F020   IPT #32 
0002 F00C   HLT 

0003 4865 hello .STR "Hello, world!" 

처음 두 열은 PC와 opcode입니다. LDA 명령어가 인코딩 된 방법이 확실하지 않습니다. (여기에서 +2 오프셋이 있습니까?)

첫 번째 단계에서 모든 주소 지정이 상대적이라고 가정하면 어셈블러는 op 코드의 고정 부분을 방출합니다 두 번째 단계에서 hello의 주소로 지침을 패치하는 데 필요한 표시기와 함께 마커와 함께 LDA RA 부분을 덮습니다.

이 시점에서 최종 기계 언어의 크기는 알지만 전체 값은 알 수 없습니다.

그런 다음 계속해서 각 명령어의 주소를 확인하고 심볼 테이블을 작성합니다.

두 번째 단계에서는 위의 정보를 알고 있으므로 상대 오프셋 등을 계산하여 각 명령을 패치합니다. 또한 종종 PC 값을 포함한 전체 출력을 재생성합니다.

간혹 두 번째 패스에서 무언가가 감지되어 계속되는 것을 방지합니다. 예를 들어 256 단어 (-127 ~ +128)의 오브젝트 만 참조 할 수 있지만 hello 레이블은 128 단어 이상 떨어져있는 것으로 나타납니다. 즉, 첫 번째 합격 동안 배운 모든 것을 변경하는 2 단어 명령어 (절대 주소 포함)를 사용 했어야합니다.

'수정 오류'라고도합니다. 동일한 단계가 링크 단계에서 발생할 수 있습니다.

단일 패스 어셈블러는 '사용하기 전에 정의'를 고집하는 경우에만 가능합니다. 이 경우 코드에서 hello을 정의되지 않은 기호로보고합니다.

또한 "프로그램 섹션"을 읽어야합니다. .STR은 실행 가능한 명령어가 아니지만 입니다.이 코드는 문자열의 이진 표현을 이미지의 CODE 섹션에 배치하는 어셈블러에 대한 지시문입니다 (vs DATA).

+0

PC 상대 오프셋은 컴퓨터 인코딩에서 2로 조정되지만 메모리는 단어로만 처리 할 수 ​​없습니다. 또한 실행 파일의 코드 섹션에 문자열과 같은 읽기 전용 데이터를 두는 것이 일반적입니다. (예 : Unix 플랫폼의 경우'.section .rodata '). –

+0

또한 가능하지만 8 또는 24 비트 명령어가 없음을 의미합니다. – kdopen

+0

또는 PC 상대 주소 지정 모드를 사용하여 주소 지정을 원하는 모든 것에 대해 최대 1 바이트의 패딩이 필요합니다. 그럴만 한 가치가있는 것 같습니다. -128 .. + 127B는 꽤 작은 범위 일 겁니다. 보통 코드와 데이터를 조금씩 분리하기를 원하기 때문입니다. –