Question

I'm a newbie when it comes to FASM, and pretty new to ASM in general, but I'm trying to compare two strings stored in the "variables": user_input and exit_cmd:

At the moment, it assembles fine but when I enter anything in the prompt it crashes. Yes, my code is messy and the task I'm trying to accomplish may seem out of my reach for the level of ASM I know, but I've done it in other languages so I'm trying it out in ASM.

You can see I'm using the macro CompareStrings (source unknown; it's not mine) to set EAX to 1 if the strings match, but when I compare EAX to 1 using CMP and then JE to a label it refuses to work. Any help?

Here's the buggy code:

format PE console
;win32a.inc, win32w.inc, win64a.inc and win64w.inc
include 'win32w.inc'
entry main

; Define macros for things like printing strings ('print') and pausing (well, waiting for the user to press enter ('pause'))
macro print str {
      push str
      call [printf]
      push 0
}
macro pause {
      invoke system,'pause>nul'
}
macro getinput prompt {
      print prompt
      invoke gets,user_input
}
macro CompareStrings str1, str2
{
      lea edi, [str2]               ; edi -> address of string2
      dec edi                       ; edi = edi - 1
      .lab1:                        ; loop through all chars and compare each of them
      inc edi                       ; ds:di --> next character in string2
      lodsb                         ; al = next char from string1. loadsb increments si automatically
      cmp [edi], al                 ; compare characters
      jne .notfound                 ; jump out of the loop if they're unequal
      cmp al, 0                     ; chars are equal, but make sure we compared the entire string
      jne .lab1                     ; if not, continue the loop
      mov eax, 1                    ; else: strings are equal -> eax = 1
      ret                           ; return; result: strings are equal
      .notfound:                    ; chars are not equal
      mov eax, 0                    ; unequal -> eax = 0
      ret                           ; return; result: strings are not equal
}

section '.text' code readable executable

main:
        print header_msg
        jmp input_loop

input_loop:
        getinput cmd_prompt
        print newline
        CompareStrings user_input,cmd_exit
        cmp eax, 1
        je exit_cmd
        jne input_loop

exit_cmd:
        print header_msg
        ret

section '.data' data readable writable
        header_msg    db      "Basic Programming Language in ASM | Version 0.0.1",13,10,0
        cmd_prompt    db      "> ",0
        newline       db      "",13,10,0
        user_input    db      "",0dh,0ah,0
        chrarr        db      '%s',0dh,0ah,0
        cmd_exit      db      'exit',0

section '.idata' import data readable

library msvcrt,"msvcrt.dll"

import msvcrt,\
       puts,"puts",\
       getchar,"getchar",\
       exit,"exit",\
       printf,"printf",\
       scanf,"scanf",\
       system,"system",\
       gets,"gets"
Was it helpful?

Solution

There are many problems in this program and it is not strange it crashes.

Problem 1

You didn't allocated enough room for the string you input. Use rb directive to allocate some big enough space to handle your input:

user_input  rb  1024

Put it at the end of the data section in order to not take place in the result executable.

Problem 2

I don't know how the CPP library have to be used, but probably the calling convention is not STDCALL and the parameters are not exactly these. For example gets probably needs some kind of CPP self expandable string, not simple buffer address. Otherwise it is very easy to overflow the buffers and there is no way to check such a problem.

So, better use plain WinAPI - ReadFile and WriteFile to read and write to the console.

Problem 3

On the above background, it is nitpicking, but anyway:

  push str
  call [printf]
  push 0

This push 0 looks weird here. What is is supposed to do?

Problem 4

Your style. Try to implement this program without using "{" and "}" characters. It will help you to understand assembly language better.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top