So I finally figured out the problem. Here is the solution for anyone that needs this in the future.
As a quick recap, the problem was taking the integer returned from the system call GET_PID and converting it to a string for use with SYS_WRITE.
The first step was to take the integer and isolate each digit; for example:
Returned PID: 60015 - Grab each integer own its own i.e. 5 1 0 0 6
To achieve this I used the DIV function to divide the integer by 10, this leaves the remainder in EDX. If we look at the math 60015/10 would result in 6001.5, so the remainder 5 would be stored in EDX. A loop can then be used to retrieve each integer until it reaches zero, followed by a JZ to exit the loop.
The next step is to take each integer and find its ASCII code to store into a buffer. To do this, a translation table is used:
LookUpDig db "0123456789"
Take the digit stored in EDX and use it as an index into the translation table, this will retrieve the ASCII version of that integer for use with sys_write.
mov cl, [LookUpDig+edx]
Take the ASCII value and insert it into the buffer for the result.
mov [ebp], cl
Place this into the loop to build the string from the integer returned.
The full program should give more context to the solution, I hope the comments are detailed enough to explain each line of code.
;*************************************************************
; Date : 02/04/2013 *
; Compile : nasm -f macho -o pid.o space.asm *
; Link : ld -macosx_version_min 10.7 -o pid pid.o *
; Descr. : Prints the process PID, could be used in a *
; larger program. *
; Nasm v. : NASM version 0.98.40 *
;*************************************************************
SECTION .data
LookUpDig db "0123456789" ; Translation Table
PIDString db "PID: "
PIDLength equ $-PIDString
SECTION .bss
PID: resb 8 ; Reserve space for result
SECTION .text
global start
start:
mov eax, 0x14 ; GET_PID call
int 0x80 ; Call
mov ebx, 0xA ; Set divider to 10
mov ebp, PID+6 ; Save the address of PID+6 to EBP
jnz LoopMe ; Run the loop to convert int to string
LoopMe:
div ebx ; Divide the PID by 10
mov cl, [LookUpDig+edx] ; Copy ASCII value to CL
mov [ebp], cl ; Copy CL to PID buffer
dec ebp ; Move to next byte in the buffer
xor edx, edx ; Clear the remainder, leave in for some weird results :)
inc eax ; Increase EAX tricking JNZ
dec eax ; Decrease to get back to original value
jnz LoopMe ; Keep looping until EAX is zero (all integers converted)
jz PrintOut ; When done call the print out function
PrintOut:
push PIDLength ; Push PIDString Length
push PIDString ; Push PIDString
push 0x1 ; FD stdout
mov eax, 0x4 ; sys_write call
push eax ; Push call (BSD)
int 0x80 ; Call
add esp, 0x10 ; Clear up the stack
mov [PID+7], byte 0xA ; Push a newline to PID string
push 0x8 ; Max length of 8 bytes
push PID ; Push PID value
push 0x1 ; FD stdout
mov eax, 0x4 ; sys_write call
push eax ; Push call (BSD)
int 0x80 ; Call
add esp, 0x10 ; Clean up stack
mov eax, 0x1 ; Set system_call
push 0x0 ; Exit_code 0
int 0x80 ; Call
I hope this helps anyone else out in the future who has the same issue.