所以我终于弄清楚了问题所在。这是将来需要此功能的任何人的解决方案。
快速回顾一下,问题在于获取从系统调用 GET_PID 返回的整数并将其转换为字符串以供 SYS_WRITE 使用。
第一步是取整数并隔离每个数字;例如:
Returned PID: 60015 - Grab each integer own its own i.e. 5 1 0 0 6
为了实现这一点,我使用 DIV 函数将整数除以 10,这将余数留在 EDX 中。如果我们看一下数学 60015/10 将导致 6001.5,所以余数 5 将存储在 EDX 中。然后可以使用循环来检索每个整数,直到它达到零,然后使用 JZ 退出循环。
下一步是获取每个整数并找到其 ASCII 码以存储到缓冲区中。为此,使用了转换表:
LookUpDig db "0123456789"
获取存储在 EDX 中的数字并将其用作转换表的索引,这将检索该整数的 ASCII 版本以用于 sys_write。
mov cl, [LookUpDig+edx]
获取 ASCII 值并将其插入结果缓冲区。
mov [ebp], cl
将其放入循环中以从返回的整数构建字符串。
完整的程序应该为解决方案提供更多的上下文,我希望注释足够详细以解释每一行代码。
;*************************************************************
; 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
我希望这可以帮助将来遇到同样问题的其他人。