Хочу, чтобы printf вывел число, а выводит символ из таблицы ASCII
format pe console
include 'C:\Program Files\FASM\INCLUDE\win32ax.inc'
include 'C:\Program Files\FASM\INCLUDE\api\kernel32.inc'
entry start
.data
i db 40
.code
start: cinvoke printf, <i>
cinvoke getch
invoke ExitProcess, 0
section '.idata' import data readable
library kernel32,'kernel32.dll',msvcrt,'msvcrt.dll'
import msvcrt, printf, 'printf', getch, '_getch', scanf, 'scanf'
Есть у меня, например, метка i со значением 40. Когда я запускаю программу, выводится "(". Я попробовал заменить cinvoke printf, <i> на cinvoke printf, <'%d'>, i, но у меня выводится число 4202496, a должно выводиться 40. Как вывести число?
Ответы (1 шт):
Здесь i - это адрес в памяти, а не значение по указанной метке. Чтобы получить значение(40), вам нужно взять i в квадратные скобки [i]. Только переменная в данном случае размером в байт, и этот байт нельзя передавать в виде аргумента функции printf() - его нужно сначала преобразовать в DWORD, т.к. именно дворд = мин.значение для стека (иначе он уйдёт с границы 4-байт). Из байта/ворда делает дворд инструкция movzx. Вот пример:
format pe console
include 'win32ax.inc'
entry start
;//------------
.data
a db 40 ;//<--- байт нельзя ложить в стек
b dw 5583 ;//<--- ворд нельзя ложить в стек
c dd 4953728 ;//<--- дворд можно
string db 10,' Press any key for exit...',0
;//------------
.code
start: invoke SetConsoleTitle,<'*** Printf example ***',0>
movzx eax,[a] ;//<--- делаем из байта дворд
movzx ebx,[b] ;//<--- делаем из ворда дворд
cinvoke printf,<10,' Address | Value ',\
10,' -----------|---------',\
10,' 0x%08x %d',\
10,' 0x%08x %d',\
10,' 0x%08x %d',\
10,' %s',0>,a,eax,b,ebx,c,[c],string ;//<--- все аргументы размером DWORD
cinvoke getch
cinvoke exit,0
;//------------
section '.idata' import data readable
library kernel32,'kernel32.dll',msvcrt,'msvcrt.dll'
import msvcrt,printf,'printf',getch,'_getch',scanf,'scanf',exit,'exit'
include 'api\kernel32.inc'
