Win64 NASM汇编整数转字符串异常问题求助
问题:Win64下NASM汇编整数转字符串仅0正常显示,其他数弹出空白框
在Win64环境使用NASM汇编实现整数转字符串,通过MessageBoxA函数显示结果时,仅数字0能正常显示,其他正整数会弹出空白消息框。已确认C++辅助编译代码无问题,问题出在汇编的整数转字符串逻辑中。
原汇编代码
default rel global WinMain extern ExitProcess extern MessageBoxA section .data title: db 'Melang64', 0 section .bss buf: resb 80 section .text WinMain: sub rsp, 28h mov rax, buf mov rdi, 1 call uitoa mov rcx, 0 lea rdx,[buf] lea r8,[title] mov r9d, 0 call MessageBoxA mov ecx,eax call ExitProcess add rsp, 28h hlt uitoa: mov rsi, rax mov rax, rdi cmp rax,0 jnz uitoa_convert_nrm mov byte [rsi], 48 inc esi mov byte [rsi], 0 jmp uitoa_end uitoa_convert_nrm: mov r10, 10 xor rcx, rcx uitoa_loop: xor rdx, rdx div r10 inc ecx cmp rax, 0 jnz uitoa_loop inc ecx add rsi, rcx mov byte [rsi], 0 mov rax, rdi dec ecx uitoa_convert: xor rdx, rdx dec rsi div r10 add rdx, 48 mov byte [rsi], dl loopnz uitoa_convert uitoa_end: ret
C++辅助代码
#include <cstdlib> #include <windows.h> #include <iostream> #include <string> int main() { std::cout << "Hello\n"; system("nasm -f win64 Hi.asm"); STARTUPINFO si = { sizeof(STARTUPINFO) }; PROCESS_INFORMATION pi; const wchar_t* command = L"\"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.38.33130\\bin\\Hostx64\\x64\\link.exe\" Hi.obj /subsystem:windows /entry:WinMain /libpath:\"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.38.33130\\lib\\x64\" /nodefaultlib msvcrt.lib /libpath:\"C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.22621.0\\um\\x64\" /nodefaultlib kernel32.lib user32.lib /largeaddressaware:no"; std::wstring writableCommand(command); if (CreateProcess(NULL, &writableCommand[0], NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } else { std::wcerr << L"Error: " << GetLastError() << std::endl; } system("Hi.exe"); return 0; }
错误分析与修正
问题出在uitoa_convert_nrm段的两个多余操作:
inc ecx:计算完数字的位数后,额外将计数器加1,导致字符串结束符被写到超出实际需要的位置。dec ecx:对应上面的多余加1操作,虽然循环次数正确,但字符串起始位置偏移了一位,最终生成的字符串从buf+1开始,而buf[0]是BSS段默认的0值(字符串结束符),MessageBoxA读取时会认为是空字符串。
修正后的汇编代码
default rel global WinMain extern ExitProcess extern MessageBoxA section .data title: db 'Melang64', 0 section .bss buf: resb 80 section .text WinMain: sub rsp, 28h mov rax, buf mov rdi, 123 ; 可替换为任意正整数测试 call uitoa mov rcx, 0 lea rdx,[buf] lea r8,[title] mov r9d, 0 call MessageBoxA mov ecx,eax call ExitProcess add rsp, 28h hlt uitoa: mov rsi, rax mov rax, rdi cmp rax,0 jnz uitoa_convert_nrm mov byte [rsi], 48 inc esi mov byte [rsi], 0 jmp uitoa_end uitoa_convert_nrm: mov r10, 10 xor rcx, rcx uitoa_loop: xor rdx, rdx div r10 inc ecx cmp rax, 0 jnz uitoa_loop ; 移除多余的inc ecx add rsi, rcx mov byte [rsi], 0 mov rax, rdi ; 移除多余的dec ecx uitoa_convert: xor rdx, rdx dec rsi div r10 add rdx, 48 mov byte [rsi], dl loopnz uitoa_convert uitoa_end: ret
内容的提问来源于stack exchange,提问作者Marnu van Sandwyk
相关产品推荐
相关产品推荐

