2017-10-26 13 views
1

GNU 어셈블리의 배열을 사용하려고합니다. 내 의견으로는 다음과 같은 코드는 값 3으로 종료해야하지만 movw inArr(%rip, %rcx, 2), %di 명령 %di = inArr[%rcx] 같은 동일하다 내 의견으로는 13AT & T GAS 어셈블리의 배열 주소 지정. RIP에서 레지스터 오프셋이 작동하지 않습니다.

.section __DATA,__data 
    inArr: 
    .word 13, 2, 3, 4, 5, 6, 7, 8, 9, 10 

    outArr: 
    .fill 10, 2 
.section __TEXT,__text 
.globl _main 
_main: 


    movq $3, %rcx 

    movw inArr(%rip, %rcx, 2), %di # load *((rcx * 2)+ rip + &inArray) into %di, isn't it? 
    movl $0x2000001, %eax   # exit 
    syscall 

으로 종료합니다. 불행히도 나는 GAS에서 array를 가진 예제를 찾을 수 없다.

그 코드에 무슨 문제가 있습니까? 그리고 배열의 n 번째 요소를 어떻게 다룰 것인가?

+0

위치 독립적 코드가 필요하지 않은 경우,'movzwl inArr (, % rcx, 2), % edi'을 사용할 수 있습니다. 하지만 OS X 용 PIC가 필요합니다 * –

+0

감사합니다! 그러면'오류 : 32 비트 절대 주소 지정은 64 비트 모드에서 지원되지 않습니다 .'라는 오류가 발생합니다. OS X 용 PIC가 무엇인지 찾을 수 없습니다. 이것을 명확히 할 수 있습니까? –

+1

PIC = 위치 독립적 코드. OS X의 x86-64 코드에서 절대 주소 지정을 사용할 수 없습니다. ([리눅스와는 달리] (https://stackoverflow.com/questions/43367427/32-bit-absolute-addresses-no-longer-allowed-in-x86-64-linux)) –

답변

2

인덱싱 된 RIP 상대 주소 지정 모드와 같은 것은 없습니다. 어셈블러에서 오류가 발생해야합니다. 이것을 대신 사용하십시오 :

lea inArr(%rip), %rdi 
    movzwl (%rdi, %rcx, 2), %edi 
+2

당신은'% rdi'를 사용할 수 있습니다. 포인터가 tmp 레지스터를 필요로하지 않도록합니다. (OP가 정말로 RDI의 하위 16 비트에 단어를 병합하기를 원하지 않는 한). –

+0

@Peter, 네, 원래 코드가 다음 줄에 다시로드했기 때문에 rax를 사용했습니다. 그러나 종료 시스템 호출은 8 비트의 하위 8 비트 만 사용하므로 동등하게 안전하며 컨텍스트없이 최상의 선택이 될 수 있습니다. – prl

+0

감사합니다. 그것은 작동합니다. 하지만 여전히 이상하게 보입니다. 제 생각에는 당신의 코드가 같은 방식으로 작동하고 있습니다. OS X에서 GAS를 사용하고 있으며 색인 생성을 무시하고 오류가 발생하지 않습니다. GAS의 배열에 대한 링크를 줄 수 있습니까? –