2013-10-12 3 views
0

값을 ascii로 변환하는 것과 관련된 몇 가지 주제를 찾았습니다. 그러나 나는 여기에 조금 붙어있다. 어셈블리 - 값을 ascii로 변환

;GetPID 

SECTION .data 

msg: db "Your PID is:"  ;pidmsg 
msgl: equ $-msg   ;pidlen 

lookup: db "" 

SECTION .bss 

pid: resb 8    ;test is a variable im testing to 
         ;receive the eax from sys_getpid 

SECTION .text 
     global _start 

_start: 
     call getpid   ;get pid number into eax 
     mov ebx,0xa 
     lea ebp, [pid+6] 
     call ASCIIC 
     jmp exit    ;exit 
exit: 
     mov eax,1 
     mov ebx,0 
     int 0x80 
getpid: 
     mov eax,20   ;getpid function (sys_getpid) 
     int 0x80 
     ret 
      ;ASCIIC was taken from http://theropfather.github.io/asm/getpid_tutorial.html 
ASCIIC: 
     div ebx       ;Divide the PID 
     mov byte cl, [lookup+edx]  ;Copy ASCII value to CL 
     mov [ebp], cl      ;Copy ASCII value to buffer 
     dec ebp       ;Next byte into buffer 
     xor edx, edx      ;Clear the remainder 
     inc eax       ;Dec eax tricking jnz 
     dec eax       ;Push back to original value 
     jnz ASCIIC       ;Keep looping until eax is zero 
     call .printPID      ;Print out the buffer 
     ret 

.printPID: 
    mov ecx, msg     ;message 
    mov edx, msgl     ;msg len 
    mov ebx,0x1      ;FD stdout 
    mov eax, 0x4     ;sys_write call 
    int 0x80       ;Call 
    mov [pid+7], byte 0xA   ;Push a newline to PID string 
    mov edx,0x8      ;Max length of 8 bytes 
    mov ecx,pid      ;Push PID value 
    mov ebx,0x1      ;FD stdout 
    mov eax, 0x4     ;sys_write call 
    ret 

그래서 여기에 포인트가 현재 프로그램 (이)의 PID 번호를 얻고 인쇄 할 수 있습니다 : 다음은 내 코드입니다. 프로그램에서 sys_getpid (eax = 20)를 호출하고 pidnumber가 반환됩니다. 그러나 sys_write 매개 변수는 다음과 같습니다. ssize_t sys_write(unsigned int fd, const char * buf, size_t count) 두 번째 인수는 char이므로 각 숫자에 대해 char로 변환해야합니다.

출력은있다 : "당신의 PID는"

누구? :)

+1

C 표준 라이브러리를 사용하지 않고 수행해야합니까? 그렇지 않다면 형식 지정자와 함께'printf'를 사용하는 것이 fd가 1 인'sys_write'보다 훨씬 쉽습니다. – us2012

+0

나는 C lib를 사용하고 싶지 않습니다. 그냥 인터럽트 및 시스템 호출. ;) – int3

답변

2
  • 실제로 숫자를 인쇄하려면 int 0x80을 잊어 버렸습니다.
  • div ebx 일 때 계산되는 것은 eax = edx:eax/ebx이므로, 귀하의 경우에는 edx이 0인지 확인해야합니다. 따라서 div ebx 앞에 xor edx,edx이 있습니다.
  • 버퍼의 앞부분을 공백으로 채워야합니다. 그렇지 않으면 stdout이 끝나는 위치에 따라 문제가 발생할 수 있습니다.
  • ebp을 사용하여 현재 버퍼 위치에 대한 포인터를 보유하는 것에 대해 매우 의심 스럽습니다. 여기서는 작동하지만 기본 포인터는 특수 목적 레지스터이므로 여기에서이를 악용 할 이유가 없습니다.
+1

또한 0 바이트를 인쇄하는 것은 좋지 않지만 터미널에서 작동하는 경우 일 수 있습니다. – Jester

+0

@Jester 좋은 지적, 감사합니다! 나는 이것과 다른 점을 더했다. – us2012

+0

옙, 뭔가 잊었 기본 : onprintID 난 0x80 인터럽트를 수행하는 것을 잊었습니다. 감사 : P – int3