1. section .data
  2.  hello db ' ) Hello, world!',10 ; Our dear string
  3. helloLen equ $ - hello ; Length of our dear string
  4.  
  5. section .bss
  6. loopctr resd 1
  7. looplimit resd 1
  8.  
  9. stringbuf resb 16              ; XXX - String for ASCII version of number (lib_print_number)
  10. stringlen resb 1               ; XXX - Length of string (lib_print_number)
  11.  
  12.  
  13. section .text
  14.  global _start
  15.  
  16. _start:
  17. mov dword [loopctr],0
  18. mov dword [looplimit],1000
  19. pop ebx ; argc (argument count)
  20. pop ebx ; argv[0] (argument 0, the program name)
  21. pop ebx ; The first real arg, a filename
  22.  
  23. mov eax,8 ; The syscall number for creat() (we already have the filename in ebx)
  24. mov ecx,00644Q ; Read/write permissions in octal (rw_rw_rw_)
  25. int 80h ; Call the kernel ; Now we have a file descriptor in eax
  26.  
  27. test eax,eax ; Lets make sure the file descriptor is valid
  28.  js skipWrite ; If the file descriptor has the sign flag ; (which means it's less than 0) there was an oops, ; so skip the writing. Otherwise call the filewrite "procedure"
  29. call fileWrite
  30.  
  31. skipWrite:
  32. mov ebx,eax ; If there was an error, save the errno in ebx
  33. mov eax,1 ; Put the exit syscall number in eax
  34. int 80h ; Bail out
  35.  
  36. ; proc fileWrite - write a string to a file
  37. fileWrite:
  38. mov ebx,eax ; sys_creat returned file descriptor into eax, now move into ebx
  39. mov eax,4 ; sys_write ; ebx is already set up
  40. mov ecx,hello ; We are putting the ADDRESS of hello in ecx
  41. mov edx,helloLen ; This is the VALUE of helloLen because it's a constant (defined with equ)
  42. jmp myloop
  43.  
  44. myloop:
  45.  
  46. call lib_print_number   ; XXX - First write the contents of loopctr to the file
  47.  
  48. push eax
  49.  int 80h ; this is where my string is written so the print number needs to be called first
  50. pop eax
  51.  inc dword [loopctr]
  52. push edx
  53. mov edx,[loopctr]
  54. cmp dword edx,[looplimit]
  55.  pop edx
  56.  je end
  57.  jmp myloop
  58.  
  59. ; endp fileWrite
  60.  
  61. end:
  62.  mov eax,6 ; sys_close (ebx already contains file descriptor)
  63. int 80h
  64.  ret
  65.  
  66.  
  67.  
  68.  
  69. lib_print_number:   ; XXX from here to end of file -- all new
  70.         pusha
  71.  
  72.     push ebx    ; Save the file descriptor for now
  73.  
  74.     mov eax, 0          ; Start converting number to ASCII
  75.     mov word ax, [loopctr]
  76.  
  77.         mov edi, stringbuf
  78.  
  79.         mov ebx, 10                     ; Base of the decimal system
  80.         mov ecx, 0                      ; Number of digits generated
  81.  
  82. .next_divide:
  83.         mov edx, 0                      ; EAX extended to (EDX,EAX)
  84.         div ebx                         ; Divide by the number-base
  85.         push edx                        ; Save remainder on the stack
  86.         inc ecx                         ; And count this remainder
  87.         cmp eax, 0                      ; Was the quotient zero?
  88.         jne .next_divide                ; No, do another division
  89.  
  90.  
  91.         mov byte [stringlen], cl       ; Save length of string
  92.  
  93. .next_digit:
  94.  
  95.         pop eax                         ; Else pop recent remainder
  96.         add al, '0'                     ; And convert to a numeral
  97.         stosb                           ; Store to memory-buffer
  98.         loop .next_digit                ; Again for other remainders
  99.  
  100.         mov al, 10                      ; Store carriage return char
  101.         stosb
  102.  
  103.         ; Now write the string to the screen
  104.  
  105.         mov eax, 4                      ; sys_write kernel call
  106.     pop ebx             ; Get file descriptor back
  107.         mov ecx, stringbuf
  108.         mov edx, 0
  109.         mov byte dl, [stringlen]
  110.         int 0x80                        ; Call kernel
  111.  
  112.         popa
  113.         ret