2014-11-14 3 views
4

어셈블리 코드를 작성하는 방법을 배우려하고 있으며 http://gnu.mirrors.pair.com/savannah/savannah//pgubook/ProgrammingGroundUp-0-8.pdf을 사용하여 작업하고 있습니다. 그것은 훌륭한 리소스이고 Macho64 형식으로 내 Mac 용 64 비트 코드를 작성하려고합니다.상대 주소 지정 오류 - Mac 10.10

절대 및 상대 주소 지정과 관련된 문제가 발생했습니다.

내 코드입니다 :

DEFAULT REL 
;PURPOSE: This program finds the maximum number of a set of data items 
; 

;VARIABLES: The registers have the following uses 
; 
; rbx - Holds the index of the data item being examined 
; rdi - Largest data item found 
; rax - Current data item 
; 
; The following memory locations are used: 
; 
; data_items - contains the item data. A 0 is used to terminate the data 
; 

global _main 

section .data 
    data_items: dw 3,67,34,222,45,75,54,34,44,33,22,11,66,0 
    ;These are the data items 

section .text 

_main:    
    mov rdi, 0   ;move 0 into index register 
    mov rax, [data_items+rbx*4] ;load the first data byte 
    mov rdi, rax  ;since this is the first item, eax is biggest 

start_loop:   ;start loop 
    cmp 0, rax   ;check to see if we've hit the end 
    je loop_exit 
    inc rdi 
    mov rax, [data_items+rbx*4] 
    cmp rdi, rax 
    jle start_loop 

    mov rdi,rax 
    jmp start_loop  

loop_exit: 
    mov rax, 0x2000001   ;1 is the exit() syscall 
    syscall 

이들은 내가 오류 메시지입니다 : 누군가가 나를 도울 수 있다면

Samuels-MBP:Starting sam$ make 
src/maximum.s:26: error: Mach-O 64-bit format does not support 32-bit absolute addresses 
src/maximum.s:30: error: invalid combination of opcode and operands 
src/maximum.s:33: error: Mach-O 64-bit format does not support 32-bit absolute addresses 

그래서 궁금했다. 상대 주소 지정 (Relative Addressing)을 찾았지만 단순한 언어로 잘못된 것을 설명하는 것을 찾을 수 없습니다.

cmp 문구가 잘못되었다는 것을 알고 있지만 그 문제를 해결할 수 있다고 생각합니다.

답변

4

Mach-O 64-bit does not support 32-bit absolute addressing because the image base is greater than 2^32.

일반적으로 단일 메모리 요소에 액세스하려면 RIP 상대 주소 지정을 사용해야합니다. 그러나 귀하의 경우에는 정적 배열 (데이터 섹션/bss 섹션에 할당 된 배열) 및 Addressing static arrays in 64 bit mode in Agner Fog's Optimizing Assembly manual 섹션에서 설명한대로
에 액세스하고 있습니다.

정적 배열을 RIP 상대 주소 지정 및 인덱스 레지스터로 액세스 할 수 없습니다.

그래서 NASM은

mov rax, [data_items+rbx*4] 

가 할 수없는 코드를 처리 할 때 RIP 상대적인 어드레스 그래서 마하 - O 64 비트가 허용되지 않은 32 비트 절대 + 인덱스 어드레스하려고하는 NASM이 오류를보고합니다.

Exampels 3.11b-3.11d Agner 's Manual에는 정적 배열에 액세스하는 세 가지 방법이 나와 있습니다. 그러나 64 비트 OSX는 32 비트 절대 주소 지정을 허용하지 않기 때문에 (Linux에서도 가능하지만) 첫 번째 예제 3.11b는 불가능합니다.

예제 3.11c는 이미지 기본 참조 점 __mh_execute_header을 사용합니다. 나는 이것을 보지 않고 3.11d는 이해하기 쉽다. 당신이 DEFAULT REL을 delcared했기 때문에 당신이에 확인해을 ommit 할 수 있어야한다

mov rax, [rsi+rbx*4] 

mov rax, [data_items+rbx*4]를 사용하여 코드를 변경

lea rsi, [rel data_items] 

그리고 다음 RIP를로드 +이 같은 레지스터에 오프셋 lea를 사용하여 [rel data_items].

+0

정말 고마워요. 그게 정확히 답이었습니다. –

+0

@LordWindy, 30 행의 오류로'cmp 0, rax'를'cmp rax, 0'으로 변경하십시오. –