C Challenge #1 in NASM (slightly modified)

+1 c student · June 12, 2015
Done on Win32.  I didn't add a check in for the dollar sign because too lazy...
; Author                                             : c student
; Created date                                       : 12/06/2015 (DD/MM/YYYY)
; Last update                                        : 12/06/2015 (DD/MM/YYYY)
; Version                                            : 1.0
; Description                                        : C Challenge #1 in Win32 NASM

section .data                                        ; initialised data section

message  db   "Please enter in a string greater than %d and no longer than %d characters: ", 0xD, 0xA, 0
strscn   db   "%30s", 0
output   db   '"%s" is accepted.', 0xD, 0xA, 0
errmsg   db   "There was an error with your input. Please try again.", 0xD, 0xA, 0
upper    dd   0
digit    dd   0

minlen   equ  0x8
maxlen   equ  0x1E

section .bss                                         ; uninitialised data section

buf resb 31 ; input buffer

SECTION .text ; code section

global _main
extern _printf
extern _scanf
extern _strlen
extern _isdigit
extern _isupper

   mov ebp, esp                                      ; set up stack
   push DWORD maxlen                                 ; max length characters
   push DWORD minlen                                 ; min length characters
   push DWORD message                                ; set up string for printf
   call _printf                                      ; print string
   add esp, 0xC                                      ; reset stack pointer

; scan input
   xor eax, eax
   push DWORD buf                                    ; set up scanf return value
   push DWORD strscn                                 ; string format
   call _scanf                                       ; input string
   cmp eax, 0x0                                      ; check return value
   jle err                                           ; handle error
   add esp, 0x4                                      ; reset stack pointer
   pop esi

; get string length
   xor eax, eax                                      ; setup up for string length
   push DWORD esi                                    ; set up buffer for strlen
   call _strlen                                      ; get string length
   mov edx, eax                                      ; relocate return
   pop esi                                           ; reset stack pointer

; test input
   xor edi, edi
   xor ecx, ecx
   cmp edi, edx                                      ; check if equal string length
   je check                                          ; exit loop if equal
   xor ebx, ebx                                      ; reset ebx
   mov BYTE bl, [esi+edi]                            ; get buffer element
   push DWORD ebx                                    ; load element
   jmp isdigit                                       ; check character
cont:                                                ; continue loop
   add esp, 0x4                                      ; reset stack pointer
   inc edi                                           ; increment loop
   jmp begin                                         ; loop

   cmp edi, minlen                                   ; check minimum length
   jl err                                            ; jump to error if < minimum length
   cmp DWORD [digit], 0x0                            ; check digits
   jle err                                           ; jump to error if < = 0
  cmp DWORD [upper], 0x0                            ; check uppercase
  jle err                                           ; jump to error if < = 0

  push DWORD buf                                    ; load buffer
  push DWORD output                                 ; load message
  call _printf                                      ; print message
  add esp, 0x8                                      ; reset stack pointer

  mov ebp, esp                                      ; reset stack pointer
  xor eax, eax                                      ; zero eax
  ret                                               ; finish

  call _isdigit                                     ; check digit
  cmp eax, 0x0                                      ; check return value
  je isupper                                        ; jump if !digit
  or DWORD [digit], 0x1                             ; digit = 1 if digit

  call _isupper                                     ; check if uppercase
  cmp eax, 0x0                                      ; check return value
  je cont                                           ; jump back to main loop if !uppercase
  or DWORD [upper], 0x1                             ; upper = 1 if uppercase
  jmp cont                                          ; jump back to main loop

  push DWORD errmsg                                 ; load error message
  call _printf                                      ; print message
  add esp, 0x04                                     ; reset stack pointer
  jmp end                                           ; finish

I have way too much time on my hands.

Post a Reply


- page 1
Oldest  Newest  Rating
0 c student · June 19, 2015
Nice, I'll check it out.
0 Tatrasiel R · June 18, 2015
I am making a site where people can work on malware analysis together and reverse malware back to source code.

It's still in beta but you're welcome to join.


I need to fix a lot of things but the forums work completely ; as well as the  code syntax highlighting.
0 c student · June 18, 2015
I'm hoping to develop for Windows and I've already familiarised the Win32 API with C.  I'm actually hoping to go into malware analysis too so I'll need to be able to debug and/or reverse win32 code so, yeah.
0 Tatrasiel R · June 16, 2015
No, ugh MASM is kind of annoying because it's win32 only and for certain things and in many examples, it requires a special env. IMHO Just stick with NASM  or maybe TASM you'll be able to make cross platform binaries.

besides, depending where you end up at,  you'll just work in already compiled binaries.
0 c student · June 16, 2015
I've never heard of the @ before.  Maybe I'll see it when I move over to MASM?
0 Tatrasiel R · June 15, 2015
the underscore bothers you that much eh?

I keep the @ habbit because most tools will require it, namely, MultiASM plugin . :D
0 c student · June 15, 2015
Ah, I found it.  I can build with the --prefix _ option so it saves me the trouble of having to manually prepend each global and extern label.  Otherwise, without the underscore, it will complain about undefined references to function X.
0 Tatrasiel R · June 15, 2015
I did some googling and its more of the CDECL 

Microsoft will prefix functions using the cdecl  calling convention with a underscore. So main and printf will become _main and _printf respectively in the Windows development environment.


Not sure why this is showing up terribly. I cannot edit it out..let me try the code tag.
0 Tatrasiel R · June 15, 2015
If I recall correctly it doesn't matter _ or not . This is part of NASM to say what is a function that you're exporting, you also may use @. I use _ for system wide functions and @ for my own functions to keep things clean.

If I get around to it , I would like to have the series on making diablo 2 run in HD as our last exercise. 
0 c student · June 15, 2015
Nice, I'll be sure to check it out later.  By the way, I've Googled around to find out the option to prefix the underscore when using extern functions in the compiling stage but had no success.  Could you provide some guidance on this?
  • 1
  • 2



Language that is commonly used in operating systems, compilers, and other low level programs.

Bucky Roberts Administrator