myatoi()

Regulamin działu
Kolorowanie składni :
[c][/c], [vb][/vb], [asm][/asm], [delphi][/delphi], [pascal[/pascal], [python][/python], [perl][/perl], [ruby][/ruby], [bash][/bash]

myatoi()

Postprzez pegaz 29 gru 2009, o 22:45

Będzie to kod programu asm przedstawiający funkcję atoi. Jest to połączenie video-kursu asm, trochę mojej dawnej wiedzy z asm, wiedza ogólna dotycząca programowania, oraz wiedza o tym jak gcc alokuje zmienne lokalne.
Pozatym:
nie wiedziałem których rejestrów mogę używać, użyłem eax, ebx, ecx, edx
nie znam instrukcji na zmianę znaku liczby, użyłem not, i dodanie 1
program był pisany pod Linuksa, jednak jak widzę z kursu pod Win będzie działał po dodaniu '_' w nazwach funkcji
Może teraz kod:
Kod: Zaznacz cały
  1.  
  2. section .text
  3.  
  4. global main
  5.  
  6. extern printf
  7. extern scanf
  8.  
  9. ;-------------------------------------------------------------------
  10. mystrlen:
  11. ;funkcja typu cdecl
  12. ;zwraca długość napisu typu NULL-terminated
  13.     mov edx, [esp+4] ; ładujemy wskaźnik napisu
  14.     mov ecx, 0       ;zerujemy licznik pętli
  15.     petla:
  16.         mov byte al, [edx+ecx] ;ładujemy kolejny znak
  17.         test al, al            ;sprawdzamy czy jest zerem
  18.         jz return
  19.         inc ecx            ;zwiększamy licznik pętli
  20.         jmp petla
  21.     return: 
  22.     mov eax, ecx ;przenosimy licznik
  23.     ret  
  24.     ;koniec
  25. ;-------------------------------------------------------------------
  26. myatoi:
  27. ;funkcja typu cdecl
  28. ;jako parametr przyjmuje napis zwraca liczbę
  29. ;w razie błędu -1
  30.     mov ebx, [esp+4] ;ładujemy napis
  31.     sub esp, 12 ;alokujemy zmienne lokalne
  32.     mov dword [esp], 1 ;potęga 10 (początkowo 10^0 )
  33.     mov dword [esp+4], 0 ;flaga znaku
  34.     mov dword [esp+8], 0 ;liczba
  35.     mov al, [ebx]
  36.     cmp al, 0x2d ;sprawdzamy czy pierwszy znak to '-'
  37.     jnz dalej
  38.     mov dword [esp+4], 1 ;ustawiamy flagę znaku
  39.     add ebx, 1     ;i możemy ominąć znak
  40.     dalej:
  41.  
  42.     push dword ebx
  43.     call mystrlen  ;obliczmy dlugosc
  44.     add esp, 4
  45.  
  46.     mov ecx, eax
  47.     dec ecx
  48.     xor edx, edx
  49.     ;eax= badany znak ;ebx=wskaznik napisu ecx=dlugosc napisu ;edx=pomoc
  50.     ;[esp]=cyfra ;[esp+4]=znak liczby ;[esp+8] liczba
  51.     petelka:
  52.         xor eax, eax
  53.         mov byte al, [ebx+ecx]              ;ładujemy kolejny znak
  54.         sub al, 0x30                        ;odejmujemy 0x30 48d
  55.         ;trzeba sprawdzić czy eax jest z przedziału <0,9>
  56.         cmp al, 0                           ;jeżeli jest poniżej zera
  57.         jl error
  58.         cmp al, 9                           ;jeżeli jest powyżej 9
  59.         jg error
  60.         ;do liczba trzeba dodać eax*zmienna lokalna
  61.         mul dword [esp]
  62.         add [esp+8], eax
  63.         ;pomnożyć zmienną lokalną przez 10
  64.         mov eax, [esp]
  65.         mov edx,10
  66.         mul edx
  67.         mov [esp],eax
  68.         ;
  69.         dec ecx
  70.         cmp ecx, -1   ;jeżeli napis się skończył
  71.         jz koniec
  72.         jmp petelka
  73.     error:
  74.         mov eax, -1
  75.         add esp, 12
  76.         ret
  77.     koniec:
  78.         mov eax, [esp+8]
  79.         mov edx, [esp+4]
  80.         test edx, edx
  81.         jz no_minus
  82.         not eax
  83.         add eax, 1
  84.         no_minus:
  85.         add esp, 12
  86.         ret
  87.     ;koniec funkcji
  88. ;--------------------------------------------------------------------
  89. main:
  90.     push napis            ;printf
  91.     call printf
  92.     add esp, 4
  93.     ;
  94.     push dword liczba
  95.     push dword fmt       ;odczytanie liczby
  96.     call scanf
  97.     add esp, 8
  98.     ;
  99.     mov eax, liczba
  100.     push dword eax
  101.     call myatoi          ;atoi
  102.     add esp, 4      
  103.  
  104.     push dword eax
  105.     push dword fmt2      ;ponowne wypisanie liczby
  106.     call printf
  107.     add esp,8
  108.    
  109.     xor eax, eax
  110.     ret
  111.  
  112. section .data
  113. napis   db  "Podaj liczbe: ", 0
  114. liczba  db  "                   ",0   ;zapomniałem jak się wypełnia 'tablice'
  115. dight   dd  0
  116. fmt db  "%s",0
  117. fmt2    db  "%d",0xd,0xa,0
  118.  


i plik Makefile:
Kod: Zaznacz cały
  1.  
  2. all:
  3.     nasm test.asm -f elf
  4.     gcc test.o -o test
  5.  


Proszę o jakieś komentarze, jakiekolwiek (napisałem jakiekolwiek, więc teraz będę przygotowany na wszystko :) )

Avatar użytkownika
pegaz
 
Posty: 17
Dołączył(a): 23 sie 2009, o 19:46

Powrót do Assembler

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 0 gości

cron