2013-04-09 5 views
1

시스템 호출을 사용하여 Ubuntu 11.04의 NASM에서 cat>filename 명령을 구현하려고합니다. 내 프로그램이 성공적으로 컴파일되고 성공적으로 실행된다. 하지만 언제든지 cat filename 명령을 실행하려고하면 "No such file or directory"라는 메시지가 표시되지만 디렉토리에있는 파일을 볼 수 있습니다. 더블 클릭으로 파일을 열려고하면 "파일을 여는 데 필요한 권한이 없습니다."라는 메시지가 나타납니다. 내 코드에서 오류를 찾도록 도와 주시겠습니까?NASM에서 cat> fileName 명령을 구현하십시오.

코드는 다음입니다 :

section .data 
    msg:  dd "%d",10,0  
    msg1: db "cat>",0 
    length: equ $-msg1 
section .bss 
    a resb 100 
     len1 equ $-a 
    b resd 1 
    c resb 100  
    len2 equ $-c 
section .txt 
    global main 
main: 
    mov eax,4 ;;it will print cat> 
    mov ebx,1 
    mov ecx,msg1 
    mov edx,length 
    int 80h 
start: 
    mov eax,3 ;;it will take the file name as input 
    mov ebx,0 
    mov ecx,a 
    mov edx,len1 
    int 80h 

    mov eax,5 ;;it will create the file by giving owner read/write/exec permission 
    mov ebx,a 
    mov ecx,0100 
    mov edx,1c0h 
    int 80h 

    cmp eax,0 
    jge inputAndWrite 
    jmp errorSegment 

inputAndWrite: 
    mov [b],eax 

    mov eax,3 ;;take the input lines 
    mov ebx,0 
    mov ecx,c 
    mov edx,len2 
    int 80h 

    mov edx,eax ;;write the input lines in the file 
    mov eax,4 
    mov ebx,[b] 
    mov ecx,c 
    int 80h 

    jmp done 
errorSegment: 
    jmp done 
done: 
    mov eax, 1 
    xor ebx, ebx 
    int 80h 

추신을 위의 코드는 RageD에서 제안을 받아서 다시 편집합니다. 그러나, 내가 만든 파일에는 "inputAndWrite"세그먼트에서 주어진 입력 줄이 포함되어 있지 않습니다. 나는 너의 제안을 찾고있다.

+0

'cat'을 다시 구현하려합니까 (즉, 파일을 연결하고 STDOUT에 인쇄하십시오) 아니면'cp '와 같은 파일을 복사하는 프로그램을 만드시겠습니까? 두 경우 모두'cat filename'으로 프로그램을 테스트하기 전에'which cat'을 체크 했습니까? 데비안 Wheezy에서'cat'은'/ bin/cat'을 출력합니다. – nrz

+0

@nrz : 구현하려고합니다 : cat> file1. 이 명령을 실행 한 후 file1은 명령 행에서 주어진 입력 행을 포함합니다. 하지만 내 프로그램을 실행 한 후 file1이 만들어졌지만 whenevr "파일을 여는 데 필요한 권한이 없습니다."라는 파일을 열려고 시도했습니다. – sabu

답변

3

사용 권한과 관련된 주요 문제는 사용 권한이 octal이고 사용자가 decimal에 나열한 것입니다. 기본 8이 아닌 기본 8에 0700을 찾고 있습니다. 대신 1c0h (16 진수로는 0700)을 사용해보십시오. 그래서 다음과 같은 코드 수정은 권한 문제를 해결해야합니다 참고로

;; This is file creation 
mov eax, 5 
mov ebx, a 
mov ecx, 01h ; Edited here for completeness - forgot to update this initially (see edit) 
mov edx, 1c0h 

빠른 가이드 (아마도 다소 오래된,하지만 대부분의 올바른에 대한) 리눅스 시스템 호출 Linux System Call Table을 사용하는 것입니다. 레지스터를 설정하는 방법을 기억하는 데 매우 유용합니다.

또 다른 중요한 문제는 파일에 쓰는 것입니다. 나는 당신이 약간의 문제에 약간 혼란스러워했다고 생각합니다. 우선, 길이 변수에주의하십시오. 조립은 "인라인"으로 수행됩니다. 즉, len1을 계산할 때 aa에서 len1 사이의 모든 거리를 계산합니다. 그게 당신의 길이 값은 다음과 같아야 말했다

.section bss 
a resb 100 
len1 equ $ - a 
b resd 1 
c resb 100 
len2 equ $ - c 

(당신의 버퍼 입력 여기 크기에 의해 당신이 제한하는 것이 중요하지만) 확인 적절한 읽는 당신이 있는지 확인해야한다 이렇게.

내가 발견 한 또 다른 중요한 문제는 어떻게 파일에 쓰려고하는지입니다. 당신은 syscall 레지스터를 뒤집었다.

;; Write to file 
mov edx, eax ;; Amount of data to write 
mov eax, 4 ;; Write syscall 
mov ebx, [b] ;; File descriptor to write out to (I think this is where you stored this, I don't remember exactly) 
mov ecx, c ;; Buffer to write out 

여기에서 더 조정할 것입니다. 우선, 멋지게 끝내려면 (segfault 없음), 나는 단지 exit을 사용하는 것이 좋습니다. 다른 프로그램에 있지 않으면 ret이 항상 제대로 작동하지 않을 수 있습니다 (특히 독립 실행 형 x86 프로그램 인 경우). 출구 콜의 코드는 다음과 같습니다 :

;; Exit 
mov eax, 1 ;; Exit is syscall 1 
xor ebx, ebx ;; This is the return value 
int 80h ;; Interrupt 

또한, 청결, 나는 당신이 줄 바꿈에 의해 버퍼링 입력을 복용하고 있다고 가정합니다. 이 경우 파일 이름 다음에 줄 바꿈 문자를 제거하는 것이 좋습니다. 이렇게하는 가장 간단한 방법은 마지막 문자 다음에 null-terminate하는 것입니다 (줄 바꿈).

;; Null-terminate the last character - this assumes it directly follows the read call 
;; and so the contents of eax are the amount of bytes read 
mov ebx, eax ;; How many bytes read (or offset to current null-terminator) 
sub ebx, 1 ;; Offset in array to the last valid character 
add ebx, a ;; Add the memory address (i.e. in C this looks like a[OFFSET]) 
mov BYTE [ebx], 0 ;; Null-terminated 

마지막으로,이 작업을 완료 할 때 파일 설명을 닫 큰 프로젝트의 예의입니다 : 그래서, 파일 이름을 입력을 읽은 후, 나는이와 비슷한 코드를 삽입합니다.즉시 종료되기 때문에 그것은 여기에 필요하지 않을 수 있지만,이 같은 보일 것이다 :

죄송합니다

;; Close fd 
mov eax, 6 ;; close() is syscall 6 
mov ebx, [b] ;; File descriptor to close 
int 80h 

편집, 내가 쓰기 문제를 놓친합니다. 값이 100 인 파일을 여는 중입니다. 원하는 것은 (읽기 및 쓰기 기능)의 경우 1입니다. 또한 버퍼가 제대로 플러시되도록하려면 sync 시스템 호출 (인수없이 시스템 콜 번호 0x24)을 사용하는 것이 좋습니다. 그러나 데이터를 입력하는 줄 바꿈이 기술적으로이 작업을 수행해야하므로 내 테스트에서이 작업은 불필요하다고 생각합니다. 그래서 코드의 업데이트 비트는 다음과 같이해야 제대로 파일을 엽니 다 :이 도움이

; Open file 
mov eax, 5 
mov ebx, a 
mov ecx, 01h 
mov edx, 1c0h 
int 80h 

희망을. 행운을 빕니다!

+0

대단히 감사합니다. RageD. 내가 너에게 앉아서 선생님처럼 좋아한다고 설명해. 다시 고마워요 – sabu

+0

@ nrz @ RageD : 모든 변경을 한 후 새로 생성 된 파일에 명령 줄에서 입력 한 입력 행이 없습니다. 위의 코드를 다시 편집하여 고려하십시오. – sabu

+0

@SaugataBose : 내 답변을 업데이트했습니다. 죄송합니다. 나는 그 미묘한 문제를 놓쳤다. 행운을 빕니다. – RageD

관련 문제