Good day!

I can not find a good way to enter the keyboard. While stopped at ReadConsoleA + atodw . But only the number is multiplied by 100 + 2428.

Code:

 .386 .model flat, stdcall _data segment _data ends _text segment option casemap:none ExitProcess proto :dword GetStdHandle proto :dword ReadConsoleA proto :dword,:dword,\ :dword,:dword,:dword includelib C:\masm32\lib\kernel32.lib include \masm32\include\masm32rt.inc .data stdin DWORD ? stdout DWORD ? cWritten DWORD ? buff byte 16 dup (0) cRead DWORD ? sss dd 0 ddd dd 0 ifmt db "%d", 0 .code start: invoke GetStdHandle, STD_INPUT_HANDLE mov stdin, EAX invoke GetStdHandle, STD_OUTPUT_HANDLE mov stdout, EAX invoke ReadConsoleA, stdin, ADDR buff, sizeof buff, ADDR cRead, 0 ;теперь buff содержит введенную строку invoke atodw, offset buff ;почему-то после выполнения atodw число получается умноженым на 100 + 2428 ;поправляем mov sss, EAX add sss, -2428 ;отнимаем 2428 mov EAX, sss mov ddd, 100 div ddd ;делим на 100 mov sss, EAX invoke wsprintf, ADDR buff, ADDR ifmt, sss ;форматируем число для вывода invoke WriteConsoleA, stdout, ADDR buff,\ sizeof buff, ADDR cWritten, 0 ;выводим число invoke ExitProcess, 0 ;завершаем процесс end start 

Tell me why it happens. And what other ways are there to enter numbers from the keyboard?

  • Now there is no way to check why atodw may not work correctly. As I understand it, this is a masm32-specific function, it is not in one standard dll, and only a fasm is at hand. In the evening I can look. Alternatively, you can use sscanf from msvcrt.dll instead. - insolor
  • I will try sscanf, thanks! - pegoopik
  • To see atodw, which is most likely in masm32rt.inc. there are no hands ... A little off topic: do you deliberately make all calculations in memory, so that the program would work as long as possible? (you could just sub eax, 2428; mov ebx, 100; div ebx registers were made so that operations are much faster than external memory ... - Mike
  • @Mike is my ~ third program :) I’m not used to it yet, I began to teach assembler half-randomly at school, I have to study it myself. Thanks, yes, variables are superfluous here. atodw is really in masm32rt.inc. - pegoopik

1 answer 1

Most likely, ReadConsoleA puts in a buffer the carriage transfer passed in windows, i.e. two bytes 0x0D and 0x0A. And the atodw function from masm32 sdk, when converting a number from an ascii representation to a binary, does not check that the numbers are in the buffer, but for each byte of the input line it performs a standard operation to convert ascii numbers to a binary representation, subtracts 0x30 from byte (ignoring overflow).

 0x0D-0x30 = 0xDD 0x0A-0x30 = 0xDA 0xDD * 10 + 0xDA = 0x97C = 2428 

So we got your mysterious number 2428 ...

After data entry, I recommend checking them for the fact that they are numbers, completing the string as soon as the first non-digit is met (as many programming languages ​​do when trying to convert a string to a number) and only after that use atodw on the string that is cleared of everything unnecessary.

those. something like that (there is nothing to check, the code is not verified):

  mov esi, offset buff nxt: mov al, [esi] inc esi cmp al, 30h jb done cmp al, 3Ah jb nxt done: dec esi xor al, al mov [esi], al 

Perhaps masm32 has ready-made functions for this, but I don’t know.

  • Yes, it seems to be true. Thank! - pegoopik
  • @pegoopik And by the way, considering that the actual binary translation consists of the same cycle and 3 more instructions could simply be entered here and now your own atodw :) By the way, look at the source in m32lib / atodw.asm so pleased me multiplication by 10 simultaneously with addition, two lea ... :) - Mike