2010-07-30 3 views
8

내가 (10.04 noobuntu) 리눅스에서 ASM을 배우고 나는 떨어져 다음 코드를 가지고 : http://asm.sourceforge.net/intro/hello.html조립, 안녕하세요 질문

section .text 
global _start ;must be declared for linker (ld) 

_start: ;tell linker entry point 

mov edx,len ;message length 
mov ecx,msg ;message to write 
mov ebx,1 ;file descriptor (stdout) 
mov eax,4 ;system call number (sys_write) 
int 0x80 ;call kernel 

mov eax,1 ;system call number (sys_exit) 
int 0x80 ;call kernel 

section .data 

msg db 'Hello, world!',0xa ;our dear string 
len equ $ - msg ;length of our dear string 

그것은 간단한 인사의 세계입니다. Linux +에서의 실행은 커널을 직접 호출합니다 (분명히). 누구든지 실제로 여기서 무슨 일이 일어 났는지 설명해 주실 수 있습니까? 나는 exx 프로세서의 & ebx 프로세서 레지스터의 정수를 읽고, & ecx, edx 데이터를 등록하고 커널이 호출 될 때 시스템 호출을 정의한다고 생각한다. 그렇다면 int 0x80이 호출 될 때 서로 다른 조합의 정수가 다른 시스템 호출을 정의합니까?

필자는 man 페이지에 좋지 않지만, 필자가 찾을 수있는 모든 관련 문서를 읽었으며, 어떤 man 페이지가 어떤 syscalls 조합을 정의하는지 알려줍니까?

아무 도움이됩니다. 라인 설명에 의해 라인이 사전에 놀라운 ... 고마워요을 것 제레미

답변

7

당신이 int 0x80 호출하면, 커널이 호출 할 기능을 결정하기 위해 eax 레지스터의 값 본다 (이은은 " syscall 번호 "). 이 번호에 따라 나머지 레지스터는 특정 사항을 의미하는 것으로 해석됩니다.

  • eax 4
  • ebx
  • ecx 데이터의 주소가
  • edx 쓰기가 포함 된 파일 기술자를 포함 포함의 수를 포함하십시오 sys_write 호출은 다음과 같이 레지스터가 설정 될 것으로 예상 바이트

자세한 내용은 Linux System Calls을 참조하십시오.

+0

고맙습니다. 그럼에도 불구하고 이것은 내 의심이고 도움이되었습니다. 더 자세히 알 수있는 곳을 말해 줄 수 있습니까? 이 syscall 정수가 설명서 페이지에 있습니까? – Jeremy

+0

시스템 호출 번호를 찾으려면 Linux 소스 헤더 파일을 자세히 조사해야합니다. 나는 현재 리눅스 머신을 가지고 있지 않기 때문에 정확한 위치를 알려줄 수는 없지만 커널 소스 트리에'include/asm/syscall.h'와 같은 것이있다. –

+0

대단히 감사합니다. v. 도움이되었습니다. – Jeremy

0

각각에 대해 다른 어셈블리 언어 명령어를 사용하기에는 너무 많은 시스템 호출이 있습니다.

대신 TRAP 명령을 호출합니다. eax 값은 호출 할 시스템 호출을 결정합니다. 다른 레지스터는 시스템 호출에 대한 인수입니다.

시스템 호출은 커널 내부에 나열됩니다.

+0

감사합니다. 정확히 어디에서 커널의 시스템 호출을 살펴보아야합니까? – Jeremy

2
section .text 
global _start ;must be declared for linker (ld) 

이 단지 (대 데이터, 데이터 읽기 전용 및 BSS 부) 재료, 어셈블리 프로그램의 "텍스트"절 단지 기계 명령 헤더이다. global 줄은 _start 함수가 "public"이라고 말하는 것과 비슷합니다. 우리는 우리가 sys_write 기능을보고있는 것을 알고 코멘트에서

_start: ;tell linker entry point 

mov edx,len ;message length 
mov ecx,msg ;message to write 
mov ebx,1 ;file descriptor (stdout) 
mov eax,4 ;system call number (sys_write) 
int 0x80 ;call kernel 

, 그래서 우리는 man 2 write 세부 사항을 얻을 수 있습니다. C 프로토 타입은 fd, *bufcount과 같은 매개 변수를 제공합니다. % ebx부터는 일치하는 것을 볼 수 있습니다 (% ebx = fd, % ecx = 쓸 문자열 및 % edx = 문자열 길이). 그런 다음 사용자 프로세스이므로 커널에게 출력을 수행하도록 요청해야합니다. 이것은 SYSCALL 인터페이스를 통해 이루어지며 write() 함수는 (분명히) 숫자 4를받습니다. INT 0x80은 Linux 커널의 SYSCALL 루틴을 호출하는 소프트웨어 인터럽트입니다.

당신은 (당신이 그 (것)들을 설치 한 가정) 리눅스 헤더 파일에있는 모든 시스템 콜의 실제 번호를 찾을 수 있습니다. 내 시스템에서는 /usr/include/sys/syscall.h을 확인하여 /usr/include/asm/unistd.h으로 이어진 다음 /usr/include/asm-i386/unistd.h으로 연결됩니다. 어디에서 보니, #define __NR_write 4.

mov eax,1 ;system call number (sys_exit) 
int 0x80 ;call kernel 

는 이전 세그먼트의 마지막 두 줄과 마찬가지로,이 단지 콜 ID를로드하고 (이 메모리 매핑과 정리의 제거) 프로그램을 종료 할 수있는 소프트웨어 인터럽트를 수행합니다.

데이터 섹션은 프로그램에서 사용한 변수를 설명합니다.

+0

아직 도움이되는 답변이 없습니다. 시간 내 주셔서 대단히 감사드립니다. – Jeremy