2013-06-19 2 views
0

저는 32 비트 어셈블리를 배우고 있으며 코드에 대한 도움이 필요합니다. 나는 인덱스 3에있는 테이블에 4를 넣으려고하는데, 인수는 assebly 코드로 전달됩니다.세그먼트 오류 - 이유가 무엇입니까

.code32 

.equ KERNEL, 0x80 # Linux system functions entry 
.equ WRITE, 0x04 # write data to file function 
.equ EXIT, 0x01 # exit program function 

.equ STDOUT, 1 


.equ argTab, 8 
.equ argLicz, 12 
.equ argN, 16 
.equ argZakres, 20 

.text 
    .globl przelicz 
    .type przelicz, @function 

przelicz: 

    pushl %ebp 
    movl %esp, %ebp 

    movl $2, %ecx 
    movl $4, %ebx 

    movl argTab(%ebp), %edx 
    movl %ebx, (%edx,%ecx,4) 


    movl %ebp, %esp 
    popl %ebp 

ret 

나는 C 코드를 실행합니다 분할 오류 (덤프 코드) : 나는 그것을 실행하면

#include <stdio.h> 

int main(){ 
    const static int n = 5; 
    int tab[n]; 
    int a; 
    for(a = 0; a < n; ++a){ 
     tab[a] = a; 
    } 
    int licz[n]; 

    przelicz(tab, licz, 50, 50); 

    for(a = 0; a < n; ++a){ 
     //printf("%d ", licz[a]); 
    } 
} 

내가 오류가 발생합니다. 존재하지 않는 메모리에 액세스하려고한다는 것을 읽었습니다. 이 문제를 어떻게 해결할 수 있습니까?

+0

코드가 32 비트 프로세스로 컴파일되고 있는지 확인 했습니까? 이 경우 큰 차이가 있습니다 – tay10r

+0

디버거를 사용하여 스테핑을 시도 했습니까? – Elazar

+0

@ 테일러 플로레스 - 그게 문제였습니다. 고맙습니다! –

답변

0

위에서 언급 한 것처럼 문제는 프로세스가 64 비트 프로세스로 컴파일되고 있다는 것입니다.

  1. x64-linuxx86-linux 아닌 다른 시스템 호출 테이블을 사용 :이 두 가지 이유에 대한 문제입니다. 직접 시스템 호출을하지 않기 때문에, 이것은 실수가 아닐 수도 있습니다. 그러나 이것은 알아 두어야 할 사항입니다. 예를 들어 writex64-linux0x04이 아니기 때문에 0x01입니다. (x64-linux 시스템 호출 번호는 this table을 참조하십시오).
  2. 분명히 x64-linux에는 더 큰 포인터 크기가 있습니다. 따라서 32 비트 주소가로드 될 때 그 주소의 임의의 32 비트 상반부가 임의의 위치를 ​​가리킬 수 있습니다. 이것은 함수의 스택에있는 값에도 영향을 미칩니다 (이 함수는 4 대신에 8 바이트 오프셋을 포함합니다).이 코드에서 문제의 원인이 대부분입니다.