You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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段的两个多余操作:

  1. inc ecx:计算完数字的位数后,额外将计数器加1,导致字符串结束符被写到超出实际需要的位置。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 13:31:09