0

I wrote a simple program in assembly code (open console and loop input until user enters 5). I want to store each input in variable input (new input will overwrite old). This is my code:

format PE console
entry start

include 'win32a.inc'

;======================================
section '.data' data readable writeable
;======================================

input      db "", 0

;=======================================
section '.code' code readable executable
;=======================================

start:
        ccall   [getchar] ; Wait for input
        cmp     eax, "5"  ; Compare input with string
        je      exit      ; If it is equal, then exit
        jne     start     ; If not, wait for input again
exit:
        stdcall [ExitProcess], 0

;====================================
section '.idata' import data readable
;====================================

library kernel,'kernel32.dll',\
        msvcrt,'msvcrt.dll'

import  kernel,\
        ExitProcess,'ExitProcess'

import  msvcrt,\
        printf,'printf',\
        getchar,'_fgetchar'

I tried to to write

    ccall   [getchar] ; Wait for inout
    cmp     eax, "5"  ; Compare input with string

    mov     [input], eax ; This line is added

    je      exit      ; If it is equal, then exit
    jne     start     ; If not, wait for input again

but I got error Operand sizes do not match.. I have searched for this error, but I didn't find anything useful.

  • `mov [input], eax` is a 4-byte value move (size of `eax`), but `input` is a `db` (byte). Try `mov [input], al` (move the low byte of `eax`). – lurker Apr 25 '15 at 12:14
  • OT: [Fast filter](http://stackoverflow.com/questions/28792723/adding-or-subtracting-color-from-an-image-in-a-picturebox-using-c-sharp/28799612?s=1|0.1143#28799612) and [floodfill example](http://stackoverflow.com/questions/28373615/create-custom-shape-for-button/28376826?s=2|0.2698#28376826) – TaW May 11 '15 at 20:24

1 Answers1

1

The eax register is a 32-bit (4 byte) register, but the data type of input is byte.

You need doubleword data to store a 32-bit value:

input      dd 0

Note: The data in eax is actually not a string. When you compare it to "5", the value "5" is converted to a 32-bit value, i.e. 0x00000005. Declaring input as a zero-length string not only made it the wrong type, it was also too small to hold a 4 byte value as it was only 1 byte large (the string terminator).

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Thanks, this works perfectly. I have just one more question: how to display address of variable `input`? I tried `ccall [printf], input`, but it displays only it's value. –  Apr 25 '15 at 12:29
  • @Mathematician171: Use a format string so that the routine knows to show the value as a number, not as a string: http://stackoverflow.com/questions/8622938/printing-out-registers-ints-to-console-fasm-winapi – Guffa Apr 25 '15 at 12:44
  • I tried it. When I write `ccall [printf], formatstring, input` it dispays address in base `10` of `textstring` variable, not `input` variable. –  Apr 25 '15 at 13:09
  • @Mathematician171: Where is `textstring` variable? – Guffa Apr 25 '15 at 13:52
  • I started my application and it displays `4198410`. This is decimal value, so I converted it to hex. Then I opened Cheat Engine and browsed memory region at this address, but it's value is `%d` (it is value of `formatstring`, I used this variable exactly same as in your link) and when I type something, that value doesn't change. –  Apr 25 '15 at 14:16
  • @Mathematician171: That's odd, that would mean that the routine would need to use the address for the format string both as format string and value to format. Are you sure that the adress points to the format string? If you put the format string after the input, then looking at the input as a string value would show `\0\0\0\0%d`, and the `\0` characters might not be visible. – Guffa Apr 25 '15 at 15:26