2009-08-06 4 views
1

저는 ASM (NASM)을 시작하면서 다음 스 니펫에 대한 도움이 필요합니다. 나는 오류/경고를 얻지 않으며, 단지 아무 것도 출력하지 않습니다. 내가 기대했던 것은 시간 (13)을 얻은 다음 그것을 출력 (4) 한 다음 종료 (1)하는 것입니다. 또한, 좋은 (좋은 NASM 선호) ASM 튜토리얼을 아는 사람이 있습니까?NASM 인쇄 시간이 출력되지 않습니다.

section .bss 
    time: resb 255 

section .text 
    global _start 

_start: 
    mov eax, 13 
    int 0x80 
    mov eax, time 

    mov edx, 255 
    mov ecx, time 
    mov ebx, 1 
    mov eax, 4 
    int 0x80 

    mov eax, 1 
    int 0x80 
+2

자신을 때리지 마십시오. 모든 어셈블리는 끔찍합니다. ;) –

+0

작업중인 플랫폼을 언급하는 것이 가치가있을 수 있습니다. –

+0

저는 NASM과 함께 64 비트 Linux에서 작업하고 있습니다. – kylc

답변

3

이것은 C로 번역 된 예제입니다. 버퍼에 eax하는 대신 eax로 포인터를 복사하고 있습니다. 여전히 쓰레기를 인쇄 할 원시 정수가 아닌 쓰기 용 char 배열을 원하므로 작동하지 않을 것입니다.

#include <stdlib.h> 

char b[255]; 

int 
main() 
{ 
     /* You wanted to do this which doesn't work 
     * because write wont take int* but char arrays 
     * *(int*)b=time(NULL); 
     */ 

     /* Instead you did */ 
     time(NULL); 
     b; 
     write(1, b, 255); 
     exit(1); 
} 
6

첫 번째 문제는 sys_time sys 호출을 이해해야한다는 것입니다. http://syscalls.kernelgrok.com/에는 다양한 sys 호출이 레지스터에 입력으로 필요로하는 것을 알려주는 유용한 차트가 있습니다.

잡았던 정도로

mov eax,13 

그러나 잡았던 또한 실제 시간을 기록 EBX에 전달 될 수있는 메모리 어드레스를 필요

좋은 시스템 콜 (13)이다.

빠른 방법은 스택에 일부 공간을 할당하는 것입니다 (스택에 아무것도 넣을 수는 없지만 sys_time 값은 덮어 쓸 것입니다. 왜 eax 값을 지정하지 않는 것이 좋을까요?).

push eax 

그런 다음

mov ebx, esp 

지금 시스템 호출 이제

int 80h 

우리가 (예 : EAX에) 스택에서 시간을 팝업 할 수

을 EBX에 스택 포인터를 공급
pop eax 

이제 eax에 cur 임대 유닉스 시간 (즉, 1월 1일 1970) 이후의 초 수

내가 속임수와 GCC를 통해 C 라이브러리와 NASM 링크에서 컴파일하고 printf와

를 사용하는 전체 예제를 제공합니다 유닉스 콘솔에 직접 인쇄 번호의 trickyness을 방지하기 위해 64 비트 리눅스에있는 경우

nasm -f elf sys_time.asm 
gcc sys-time.o -o sys-time 

비록와

[SECTION .data] 
PrintNum db "%d",10,0 ;this is a c string so is null terminated 
[SECTION .text] 
extern printf  
global main 

main: 
     push ebp 
    mov ebp,esp 
    push ebx 
    push esi 
    push edi  ; stuff before this for glibc compatibility 

    mov eax, 13 
    push eax 
    mov ebx, esp 
    int 0x80 
    pop eax 

    push eax  ; push eax onto stack then the format string, then call printf to write eax to console, unwind stack pointer 
    push PrintNum 
    call printf 
    add esp,8 


    pop edi   ; stuff after this for glibc compatibility 
    pop esi 
    pop ebx 
    mov esp,ebp 
    pop ebp 
    ret 

컴파일 당신이해야 할 (및 관련 multilib의 GCC와의 glibc가) 있습니다. 푸시 앤 팝을 사용하고 32 비트 레지스터를 64 비트 스택으로 푸시 할 수 없기 때문에이 프로그램을 네이티브 64 비트 실행 파일로 컴파일 할 수 없습니다.

nasm -f elf32 sys_time.asm 
gcc -m32 sys-time.o -o sys-time 

그럼 당신은 내가 32 비트 및 64 비트 리눅스에서이 테스트를 컴파일 위의 코드를 얻기 위해 관리했습니다

$ ./systime 
1310190574 

받아야합니다. 문제가 있으면 알려주세요.

귀하의 질문에 대한 nasm 튜토리얼에 대한 답변을 얻기 위해 저는 Jeff Duntemann이 최근에 "Assembly Language Step By Step, Third Edition"에서 배웠습니다. 자세한 내용 및 샘플 챕터는 http://www.duntemann.com/assembly.html을 참조하십시오.

관련 문제