Что я неправильно делаю? Хочу вывести строку Code (Text): AA:BB:CC:DD:EE:FF Делаю Code (Text): .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\masm32.inc include \masm32\include\user32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib includelib \masm32\lib\user32.lib .data szformatMAC db '%.02X:%.02X:%.02X:%.02X:%.02X:%.02X',0 crlf db 13,10,0 buffsz db [MAX_PATH] dup (0) abc db 0aah,0bbh,0cch,0ddh,0eeh,0ffh .code start: lea esi,abc invoke wsprintf,addr buffsz, addr szformatMAC, byte ptr[esi+0],\ byte ptr[esi+1],\ byte ptr[esi+2],\ byte ptr[esi+3],\ byte ptr[esi+4],\ byte ptr[esi+5] invoke StdOut, addr buffsz invoke StdOut, addr crlf invoke ExitProcess,0 end start Но на выходе - Code (Text): AA:BB0000:00:CC:DD0000:00
_sheva740 Точки в спецификации не нужны. Но это ерунда. А гонит, по всей видимости, masm. Вместо того, чтобы выдать ошибку на byte ptr[esi+5] и т.п., т.к. запихать байт в стек ну никак нельзя, он выдумывает собственный код, которым ещё и стековое выравнивание нарушает: Code (Text): push 0 mov al,byte ptr [esi+5] movzx ax,al push ax Видимо, рассчитывает, что push 0 всего два байта на стеке займёт, вот только перфикс 66 к нему поставить забывает.
Попробуй проще сделать Code (Text): abc dd 0aah,0bbh,0cch,0ddh,0eeh,0ffh и Code (Text): invoke wsprintf,addr buffsz, addr szformatMAC, dword ptr [esi+0*4],\ dword ptr [esi+1*4],\ dword ptr [esi+2*4],\ dword ptr [esi+3*4],\ dword ptr [esi+4*4],\ dword ptr [esi+5*4] А это Code (Text): mov al,byte ptr [esi+5] movzx ax,al push ax Расчитано на 16-битные программы, но invoke не обновлялся для 32-битных, а для 64-бит вообще не делался.
По ходу дела invoke разворачивается в виде текста, а не в виде опкодов. Подставление опкода это уже следующий этап. Для 32-бит push ax разумеется с префиксом 66h.
s_d_f l_inc Спасибо! Вот так получилось как и советовалось. Code (Text): xor eax,eax movzx eax,byte ptr [esi]+5 push eax movzx eax,byte ptr [esi]+4 push eax movzx eax,byte ptr [esi]+3 push eax movzx eax,byte ptr [esi]+2 push eax movzx eax,byte ptr [esi]+1 push eax movzx eax,byte ptr [esi]+0 push eax push offset szformatMAC push offset buffsz call wsprintf Выход Code (Text): AA:BB:CC:DD:EE:FF
Code (Text): call wsprintf Там еще нужно теперь стэк в ручную очищать. Именно поэтому, чтобы избежать этой проблемы я и предлагал в примере перейти в к dword`ам. Идеальным решением был-бы самодельный макрос invoke, уже правильно запихивающий байты и WORD`ы в стэк.
s_d_f Спасибо. Уже понял ))) Code (Text): xor eax,eax movzx eax,byte ptr [esi]+5 push eax movzx eax,byte ptr [esi]+4 push eax movzx eax,byte ptr [esi]+3 push eax movzx eax,byte ptr [esi]+2 push eax movzx eax,byte ptr [esi]+1 push eax movzx eax,byte ptr [esi]+0 push eax push offset szformatMAC push offset buffsz call wsprintf add esp,4*8
_sheva740 Ну и зачем все эти "извращения"? Просто замени в своем коде byte ptr на dword ptr и у-се Ну нарвешься на невыравненное чтение, ну потеряешь несколько единиц или даже десятков тактов, и что - от этого мир перевернется?!
leo Не ну как же ... Code (Text): .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\masm32.inc include \masm32\include\user32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib includelib \masm32\lib\user32.lib .data szformatMAC db '%.02X:%.02X:%.02X:%.02X:%.02X:%.02X',0 crlf db 13,10,0 buffsz db [MAX_PATH] dup (0) abc db 0aah,0bbh,0cch,0ddh,0eeh,0ffh .code start: lea esi,abc invoke wsprintf,addr buffsz, addr szformatMAC, dword ptr[esi+0],\ dword ptr[esi+1],\ dword ptr[esi+2],\ dword ptr[esi+3],\ dword ptr[esi+4],\ dword ptr[esi+5] invoke StdOut, addr buffsz invoke StdOut, addr crlf invoke ExitProcess,0 end start ... получится же ... Code (Text): DDCCBBAA:EEDDCCBB:FFEEDDCC:FFEEDD:FFEE:FF ... или я не уловил? ))
Painter Ну да (если под "под виндой" имеется в виду 32-битный режим). Именно поэтому s_d_f всё верно написал. И наоборот тоже. В 16-битном режиме нужно ставить 66, чтобы работать с 32-битными регистрами.
_sheva740 вы выводите 2е младших цифры. можно еще abc db 0aah,0bbh,0cch,0ddh,0eeh,0ffh ... push ebp mov ebp, esp mov eax, abc push eax shr eax,8 push eax shr eax,8 ... ; итд call wsprintf leave вообщето асм это низкий уровень, язык трюков в настоящий момент. потому, особенно поначалу, не стоит пользоваться макросами вообще. макроразворачиватель не делает никаких предположений и не заметит ошибки, если такое может быть развернуто. а кодогенератор не заметит ошибки, если такое может быть оттранслировано в код. для трюков это преимущество.