64x Windows 程序集中的 Int 到字符串(nasm)

问题描述 投票:0回答:1

我正在尝试将整数转换为字符串,然后使用 MessageBoxA 函数显示它。如果数字是 xero 则成功,但任何其他正整数都会显示为空白弹出消息。

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++ 程序,只需将命令发送到命令提示符以创建 obj 文件,链接它,然后运行 exe:

#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;
}

C++ 程序不是问题,但是我相信将整数转换为字符串的 asm 部分是问题。

我使用的是nasm,我使用的是windows机器。我正在为 64 位编写。

我的汇编知识不是最好的,但我尽力确保所有寄存器以及函数调用都是正确的。该程序运行完美,只是没有显示应有的数字,并且在代码上下文中显示空白消息或缓冲区。

assembly nasm messagebox
1个回答
0
投票

你的2系列除法的方法是低效,但它是正确的除了你把终止零一个字节放得太远。因此,Windows 在您提供的缓冲区中看到一个空字符串。

目前将数字1转换得到的是:

0, '1', 0
^
buf
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                   <<<<<<< Remove this line!
    add  rsi, rcx

    mov  byte [rsi], 0
    mov  rax, rdi
    dec  ecx                   <<<<<<< Remove this line too!

uitoa_convert:                 RCX is at least 1 at this point
    xor rdx, rdx
    dec  rsi
    div  r10
    add  rdx, 48
    mov  byte [rsi], dl
    loopnz uitoa_convert       <<<<<<< Just use LOOP (still inefficient)

uitoa_end:
    ret
© www.soinside.com 2019 - 2024. All rights reserved.