2013-10-12 5 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 для каждого числа.

выход только: "Ваш ПИД:"

Кто-нибудь? :)

+1

Вам нужно сделать это без использования стандартной библиотеки C? Если нет, использование 'printf' с спецификатором формата будет намного проще, чем' sys_write' с fd 1. – us2012

+0

Я не хочу использовать C lib. Просто прерывания и системные вызовы. ;) – int3

ответ

2
  • Вы забыли int 0x80 во второй раз, чтобы на самом деле распечатать номер.
  • Когда вы div ebx, подсчитано eax = edx:eax/ebx, поэтому вы должны убедиться, что edx равно нулю в вашем случае. Итак xor edx,edx перед вами div ebx.
  • Вы должны прокладывать переднюю часть своего буфера пробелами, иначе вы можете столкнуться с проблемами в зависимости от того, где закончится stdout.
  • Я очень подозрительно отношусь к вашему использованию ebp, чтобы удерживать указатель на текущую позицию буфера. Хотя он работает здесь, базовый указатель является регистром специального назначения, и я не вижу причин злоупотреблять им здесь.
+1

Кроме того, печать нулевых байтов не является приятной, но может случиться, что она работает для терминала. – Jester

+0

@Jester Хорошая точка, спасибо! Я добавил это и еще один момент. – us2012

+0

yup, забыл что-то основное: on .printPID я забыл сделать прерывание 0x80. :) спасибо: P – int3

Смежные вопросы