HasanRasulov

trailingzeroswithoutfunctions.asm

Jan 28th, 2021
1,156
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. section .bss
  3. num resb 10
  4. section .data
  5. section .text
  6.  
  7. atoi:
  8.     push    ebx             ; preserve ebx on the stack to be restored after function runs
  9.     push    ecx             ; preserve ecx on the stack to be restored after function runs
  10.     push    edx             ; preserve edx on the stack to be restored after function runs
  11.     push    esi             ; preserve esi on the stack to be restored after function runs
  12.     mov     esi, eax        ; move pointer in eax into esi (our number to convert)
  13.     mov     eax, 0          ; initialise eax with decimal value 0
  14.     mov     ecx, 0          ; initialise ecx with decimal value 0
  15.  
  16. .multiplyLoop:
  17.     xor     ebx, ebx        ; resets both lower and uppper bytes of ebx to be 0
  18.     mov     bl, [esi+ecx]   ; move a single byte into ebx register's lower half
  19.     cmp     bl, 48          ; compare ebx register's lower half value against ascii value 48 (char value 0)
  20.     jl      .finished       ; jump if less than to label finished
  21.     cmp     bl, 57          ; compare ebx register's lower half value against ascii value 57 (char value 9)
  22.     jg      .finished       ; jump if greater than to label finished
  23.  
  24.     sub     bl, 48          ; convert ebx register's lower half to decimal representation of ascii value
  25.     add     eax, ebx        ; add ebx to our interger value in eax
  26.     mov     ebx, 10         ; move decimal value 10 into ebx
  27.     mul     ebx             ; multiply eax by ebx to get place value
  28.     inc     ecx             ; increment ecx (our counter register)
  29.     jmp     .multiplyLoop   ; continue multiply loop
  30.  
  31. .finished:
  32.     cmp     ecx, 0          ; compare ecx register's value against decimal 0 (our counter register)
  33.     je      .restore        ; jump if equal to 0 (no integer arguments were passed to atoi)
  34.     mov     ebx, 10         ; move decimal value 10 into ebx
  35.     div     ebx             ; divide eax by value in ebx (in this case 10)
  36.  
  37. .restore:
  38.     pop     esi             ; restore esi from the value we pushed onto the stack at the start
  39.     pop     edx             ; restore edx from the value we pushed onto the stack at the start
  40.     pop     ecx             ; restore ecx from the value we pushed onto the stack at the start
  41.     pop     ebx             ; restore ebx from the value we pushed onto the stack at the start
  42.     ret
  43.  
  44.  
  45.  
  46.  
  47.  
  48. global _start      
  49.    
  50. _start:                
  51.      
  52.  
  53.     mov eax,3
  54.     mov ebx,0
  55.     mov ecx,num
  56.     mov edx,10
  57.     int 80h
  58.  
  59.     mov ebx,1    ;divident
  60.     mov ecx,0    ;number of zeros
  61.     mov edx,5    ;to multiply the divident
  62.     mov eax,0    ;quotient of divison
  63.  .loop:
  64.     add ecx,eax  ;add the quotient of result
  65.     mov eax,ebx  ;move divident to eax
  66.     mov edx,5    ;move 5 to edx to multiply  
  67.     mul edx      ;multiply last divident with 5
  68.     mov ebx,eax  ;move divident to ebx
  69.  
  70.     mov eax,num  ;move number to eax to call atoi
  71.     call atoi    
  72.  
  73.     div ebx      ;divide number by current divident
  74.     cmp eax,1    ;if quotient is less than 1 finish
  75.     jge .loop      
  76.    
  77.  
  78. out:
  79.     mov eax,ecx   ;move result to eax to print
  80.  
  81.       ;iprint label will print the integer number in eax to stdout
  82.      
  83.        
  84.  
  85. .iprint:
  86.     mov     ecx, 0          ; counter of how many bytes we need to print in the end
  87.     mov     esi, 10         ; mov 10 into esi
  88. .divideLoop:
  89.     inc     ecx             ; count each byte to print - number of characters
  90.     mov     edx, 0          ; empty edx
  91.     idiv    esi             ; divide eax by esi
  92.     add     edx, 48         ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction
  93.     push    edx             ; push edx (string representation of an intger) onto the stack
  94.     cmp     eax, 0          ; can the integer be divided anymore?
  95.     jnz     .divideLoop      ; jump if not zero to the label divideLoop
  96.  
  97. .printLoop:
  98.     dec     ecx             ; count down each byte that we put on the stack
  99.      
  100.     mov esi,ecx             ;store number of digits is esi to move stack pointer there
  101.    
  102.  
  103.     mov     ecx, esp        ; mov the stack pointer into eax for printing
  104.     mov     edx, 1  
  105.     mov     eax, 4
  106.     mov     ebx, 1    
  107.     int     80h  
  108.  
  109.     mov ecx,esi             ;get back number of digits
  110.  
  111.     pop     eax             ; remove last character from the stack to move esp forward
  112.     cmp     ecx, 0          ; have we printed all bytes we pushed onto the stack?
  113.     jnz     .printLoop      ; jump is not zero to the label printLoop
  114.  
  115.  
  116.   .exit:  
  117.     mov     ebx, 0
  118.     mov     eax, 1
  119.     int     80h
  120.      
RAW Paste Data