All pastes #2083082 Raw Edit

Mine

public text v1 · immutable
#2083082 ·published 2011-09-26 16:11 UTC
rendered paste body
#############################################################################
# string.S - assembly string routines by Gordon Miller 2002
# AT&T Syntax - GCC calling convention - pentium align optimized
#############################################################################

#include <gord-asm/gord-asm.h>

#############################################################################
# unsigned int gord_itoa (unsigned int i, char *a)
#############################################################################

.section .bss                     # Section declaration

.align  4
.lcomm  revstr, INTLEN+1          # Reserve space for string

#############################################################################

.text                             # Section declaration
.align  16

.global gord_itoa                   # Entry point for linker
  .type gord_itoa,@function

gord_itoa:

  pushl %edi                      # Save registers ...
  pushl %esi
  pushl %ebx
  pushl %ecx
  pushl %edx

# Get reversed ascii string into 'revstr' ...

myrevinit:
  movl  24(%esp), %eax            # Put 'i' in eax
  xorl  %ebx, %ebx                # Initialize digit count
  movl  $10, %ecx                 # Put 10 in ecx for divide
  movl  $revstr, %edi             # Put address of 'revstr' in edi
  movl  28(%esp), %esi            # Put address of 'a' in esi

mymore:
  xorl  %edx, %edx                # Initialize unsigned division
  divl  %ecx                      # Divide 'i' by 10
  addb  $ASCZERO, %dl             # Convert remainder digit to ascii
  movb  %dl, (%edi, %ebx)         # Move this digit to 'revstr'
  incl  %ebx                      # Increment digit count
  testl %eax, %eax                # While more digits ...
  jne   mymore                    # ... round again

  movl  %ebx, %eax                # Return len

# Reverse copy 'revstr' to 'a'

myrevcopy:
  movb  -1(%edi, %ebx), %dl       # Move digit in 'revstr' ...
  movb  %dl, (%esi)               # ... to 'a'
  incl  %esi                      # Next output digit
  decl  %ebx                      # Decrement digit count ...
  jne   myrevcopy                 # ... round again if more digits

  movb  $0, (%esi)                # Zero terminate 'a'

  popl  %edx                      # Restore registers
  popl  %ecx
  popl  %ebx
  popl  %esi
  popl  %edi
  ret                             # Return from 'gord_itoa'

.Lfe1:
  .size gord_itoa,.Lfe1-gord_itoa

#############################################################################
# unsigned int gord_atoi (char *str)
#############################################################################

.text                             # Section declaration
.align  16

.global gord_atoi                   # Entry point for linker
  .type gord_atoi,@function

gord_atoi:

  pushl %ebx                      # Save registers ...
  pushl %ecx
  pushl %edx
  pushl %esi

  xorl  %eax, %eax                # Initialize conversion
  movl  20(%esp), %esi            # Pointer to string

  cmpb  $0, (%esi)                # Test for NULL string ...
  je    myend2                    # ... returns 0

  xorl  %ebx, %ebx                # Clear ebx for char
  movl  $10, %ecx                 # Load ecx with 10 for multiply

mymore2:
  movb  (%esi), %bl               # Get char into bl
  subb  $ASCZERO, %bl             # Convert to digit
  jb    mybad                     # Check bounds
  cmpb  $9, %bl
  ja    mybad
  addl  %ebx, %eax                # Add to running total
  js    myflow                    # Check for little overflow
  incl  %esi                      # Next char ...
  cmpb  $0, (%esi)                #  ... test for end of string
  je    myend2
  mull  %ecx                      # Multiply running total by 10
  jc    myflow                    # Check for overflow
  testl $0x80000000, %eax         # Check for little overflow
  jne   myflow
  jmp   mymore2                   # Round again ...

mybad:
  movl  $-2, %eax                 # Return -2 if bad string
  jmp   myend2

myflow:
  movl  $-1, %eax                 # Return -1 if overflow

myend2:
  popl  %esi                      # Restore registers
  popl  %edx
  popl  %ecx
  popl  %ebx
  ret                             # Return from 'gord_atoi'

.Lfe2:
  .size gord_atoi,.Lfe2-gord_atoi

#############################################################################
# unsigned int gord_strlen (char *str)
#############################################################################

.text                             # Section declaration
.align  16

.global gord_strlen                 # Entry point for linker
  .type gord_strlen,@function

gord_strlen:

  pushl %ebx                      # Save registers ...

  movl  8(%esp), %ebx             # Pointer to string
  movl  %ebx, %eax
  cmpb  $0, (%eax)                # Test for end of string
  je    myend3

mymore3:
  incl  %eax                      # Increase len count
  cmpb  $0, (%eax)                # Test for end of string ...
  jne   mymore3                   # ... round again

myend3:
  subl  %ebx, %eax                # Length

  popl  %ebx                      # Restore registers
  ret                             # Return from 'gord_strlen'

.Lfe3:
  .size gord_strlen,.Lfe3-gord_strlen