2011-08-20 4 views
0

나는 어떤 종류의 어셈블리에서도 프로그래밍에 익숙하지 않다. 그리고 리눅스 용 NASM 타입 어셈블리가 DOS 기반 어셈블리에 비해 비교적 간단하다고 들었 기 때문에 나는 그것을 시도하기로 결정했다.Linux 어셈블리; 논쟁 목록이 나아 간다

이 내 프로그램은 지금까지입니다 :

section .data 
    opening: db 'Opening file...',10 
    openingLen: equ $-opening 
    opened:  db 'File opened.',10 
    openedLen: equ $-opened 
    bad_params: db 'Usage: writeFile filename.ext',10 
    bad_paramsLen: equ $-bad_params 
    not_opened: db 'Unable to open file. Halted.',10 
    not_openedLen: equ $-not_opened 
    hello:  db 'Hello, this is written to a file' 
    helloLen: equ $-hello 
    success: db 'Successfully wrote to file.',10 
    successLen: equ $-success 

section .bss 
    file:  resd 1 

section .text 
    global _start: 

_start: 
    pop ebx    ; pop number of params 
    test ebx,2   ; make sure there are only 2 
    jne bad_param_list 
    pop ebx 

    mov eax,4   ; write out opening file msg 
    mov ebx,1 
    mov ecx,opening 
    mov edx,openingLen 
    int 80h 

    mov eax,5   ; open file 
    pop ebx 
    mov ecx,64 
    mov edx,777o   ; permissions of file 
    int 80h 
    mov dword [file],eax 

    test dword [file],0 
    jle bad_open 

    mov eax,4   ; write successful open message 
    mov ebx,1 
    mov ecx,opened 
    mov edx,openedLen 
    int 80h 

    mov ebx,file   ; write to file (4 already in eax) 
    mov ecx,hello 
    mov edx,helloLen 
    int 80h 

    mov eax,6   ; close file 
    mov ebx,file 
    int 80h 

    mov eax,4   ; write successfully written msg 
    mov ebx,1 
    mov ecx,success 
    mov edx,successLen 
    int 80h 

    mov eax,1   ; exit 
    mov ebx,0 
    int 80h 

bad_param_list: 
    mov eax,4   ; write that params are bad 
    mov ebx,1 
    mov ecx,bad_params 
    mov edx,bad_paramsLen 
    int 80h 

    mov eax,1   ; exit with code 1 
    mov ebx,1 
    int 80h 

bad_open: 
    mov eax,4   ; write that we couldn't open the file 
    mov ebx,1 
    mov ecx,not_opened 
    mov edx,not_openedLen 
    int 80h 

    mov eax,1   ; exit with code 2 
    mov ebx,2 
    int 80h 

목표는 라이브러리 함수없이 파일에 텍스트 문자열을 작성하는 것입니다; 나는 리눅스 커널만을 사용하고있다. 저는 여기 저기에 괄호가 빠져있는 것에 약간의 문제가있었습니다, 그리고 여러분이 멍청한 놈들에게서 기대할 수있는 나머지 모든 실수들에 대해, 저는 이것이 현재 대부분 통제하에 있다고 생각합니다.

여기 내 문제가있다 :이 프로그램의 처음 네 줄은 스택에서 인수의 수를 띄우고, 하나의 매개 변수 (프로그램 이름 제외)가있을 경우 bad_param_list으로 점프하고 pop 스택에서 프로그램 이름.

그러나 이것은 발생하지 않습니다. 여기에 I/O를 명확하게하기 위해 포맷 몇 가지 예제는 다음과 같습니다

$./writeFile 
Opening file... 
Unable to open file. Halted. 

$./writeFile x 
Usage: writeFile filename.ext 

$./writeFile x x 
Usage: writeFile filename.ext 

$./writeFile x x x 
Opening file... 
Unable to open file. Halted. 

$./writeFile x x x x 
Opening file... 
Unable to open file. Halted. 

$./writeFile x x x x x 
Usage: writeFile filename.ext 

$./writeFile x x x x x x 
Usage: writeFile filename.ext 

내가 발견 한 것은 당신이 2로 프로그램의 이름, 나누기를 포함하여 인수의 수를 고려해야하고, 경우, 소수점을 무시하는 경우 대답은 이상합니다. 내 사용 오류가 발생하지만 답변이 짝수이면 오류를 열 수 없습니다. 이것은 적어도 10 개의 논쟁까지 사실입니다!

어떻게 이런 일을 할 수 있었습니까? 그리고 예상되는 결과를 얻으려면 어떻게해야합니까? 대신

test ebx,2 

+1

왜 모든 시작 어셈블리 프로그래머는 그들이 찾을 수있는 가장 뼈없는 인터페이스로 작동하는 완전한 프로그램을 작성하여 시작한다고 결정하는 것입니까? C 프로그램에 링크하고 I/O를 위해 기존의 C 런타임 라이브러리를 사용하는 어셈블러 함수를 작성하는 것이 훨씬 쉽고, 유용하며, 양도 할 수있는 기술입니다. 나는 저수준의 것을 마스터 링하는 것이 _useless_ (그것은 아니다)라고 말하지는 않지만, 그것은 좀 더 밀교적이고 전문화되어있다. 자신을 "초보자"라고 부르는 경우, 먼저 기본적인 것을하지 않고 덜 간단한 작업을 수행하십시오. –

+0

내가 그 결정을 한 주요 이유는 다음과 같습니다. 나는 프로그래밍에있어서가 아니라 _assembly_에서 초보자이다. 나는 조립식을 배우고 싶다. 왜냐하면 나는 뼈의 수준에 무엇이 있는지 이해하는 데 관심이 있기 때문이다. 라이브러리를 사용하려면 C 또는 C++로 작성합니다. 편집 : 죄송합니다. 방금 깨달은 것이 조금 엉뚱한 것 같습니다. 그것은 내가 의도 한 바가 전혀 아닙니다. – Mrrvomun

+0

문제는이 방법을 사용하면 Linux가 프로세스를 초기화하는 방법이나 시스템 콜 인수가 마샬링되는 방법에 대한 일반적으로 관련없는 세부 정보를 학습하면서 같은 시간에 어셈블리를 가르치려고하는 것을 끝낼 수 있다는 것입니다.어셈블리에 무언가를 쓸 이유가있는 가장 실질적인 경우에는 커널이나 응용 프로그램에서 C 코드로 인터페이스하는 것이 좋습니다. 반대로, 시스템 콜을 배우는 것은 _ 여러분이 libc 관리자가되기를 원할 때만 _ 가능할 것입니다. _Loringage_ 대신에 기존의 C 지식 _ignoring_ 그것! –

답변

0

당신은

cmp ebx,2 

test은 비트 단위로 수행 사이의 인수와 플래그를 설정을 제외하고, 멀리 결과를 발생합니다. 따라서 두 인수가 일치하는 위치에 1 비트가없는 경우 특히 ZF가 설정됩니다. (특별한 경우에, 이것은 ZF를 ebx의 두 번째 - 최저 비트의 보수로 설정하는 것으로 작동합니다).

반대로 cmp은 인수를에서 뺍니다. 플래그를 설정 한 후 결과를 버립니다. 이 경우 두 인수가 이 같고 인 경우 ZF가 설정됩니다.

+0

_Sigh_. 나는 NASM을위한 좋은 온라인 참고 자료 또는 튜토리얼이 있었으면 좋겠다. 이것은 매우 간단한 문제에 대한 매우 간단한 해결책 인 것처럼 보입니다. 그리고 그것은 작동합니다. 더 이상 임의로 'bad_param_list'로 점프! 정말 고마워! 나는 당신이 질문에 대답했기 때문에 지금 당신에게 받아 들여진 대답을 주겠지 만, 당신이 이것에 대한 간단한 해결책을 가지고 있는지 궁금 해서요. 그것은 여전히'파일을 열 수 없습니다. '라고 말하고 있습니다. 파일의 존재 여부는 중요하지 않습니다. 내 바보 같은 또 다른 바보 같은 오류입니까, 아니면 그것에 대해 새로운 질문을해야합니까? 다시 한 번 감사드립니다! – Mrrvomun

+0

아무 것도하지 않고 ebx를 세 번 터뜨리는 것은 약간 비 슷한 것처럼 보이지만, syscall과 프로세스 초기화 규칙이 실제로 의미가 있는지 여부를 확인하는 데 신경 쓰지는 않습니다! –

+0

@hennig makholm : OOhhh. 그것은 모두 완벽하게 이해됩니다! 나는 cmp와 jg, jl, je, jle, jge가 어떻게 작동하는지 궁금해했다. (내가 책을 읽었을 때 은 두 개의 숫자를 비교한다고 말합니다. 왜냐하면 나는 그 책에서 충분히 을 얻지 못했기 때문입니다 ...) 그래서 7> 2, 7-2 = 5 , 5는 양수가 이므로 더 큽니다. 마찬가지로 2 <7, 2-7 = -5, -5는 음수이므로 이 적고 2 = 2, 2-2 = 0이면 0이므로 동일합니다. wierd 코멘트에 대해 유감스럽게 생각합니다. 은 마침내 이해하기에 좋은 느낌입니다. –

관련 문제