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

MASM x86下TCP聊天程序字符串拼接及预定义字符串存储问题

解决MASM x86中添加前缀后程序崩溃及字符串存入局部变量的问题

听起来你已经搞定了获取计算机名的部分,但在加前缀时踩了内存的坑——这在x86汇编里太常见了,尤其是栈上的局部变量空间不够或者字符串处理没做好的时候。我来一步步帮你解决:

一、先搞清楚崩溃的核心原因

你原来用80字节存计算机名没问题,但加前缀后,总长度肯定超过80字节了,直接往原来的缓冲区里塞会栈溢出,覆盖栈上的ebp、返回地址这些关键数据,程序不崩溃才怪。另外,如果手动拼接字符串时没处理好NULL终止符,后续调用函数也会读到非法内存。

二、正确的实现步骤(附代码示例)

我们需要分三步:定义足够大的缓冲区、把前缀复制进去、追加计算机名,全程用Windows API来处理字符串,比手动字节复制靠谱得多。

1. 定义合适的局部变量

首先在栈上定义两个缓冲区:一个临时存计算机名,一个存最终的前缀+计算机名(要留足空间,比如100字节足够应对大部分情况),还要一个变量存GetComputerName需要的长度参数。

2. 把预定义前缀存入局部变量

用lstrcpy API直接把.data段里的前缀字符串复制到栈上的缓冲区,比手动逐个mov字节高效还不容易错。

3. 获取计算机名并追加到前缀后面

先把计算机名读到临时缓冲区,再用lstrcat API追加到前缀缓冲区的末尾,自动处理NULL终止符。

完整代码示例:

.386
.model flat, stdcall
option casemap:none

; 引入需要的Windows API
include windows.inc
include kernel32.inc
includelib kernel32.lib

.data
; 预定义的前缀字符串
szPrefix db 'Computer Name: ', 0

.code
main proc
    push ebp
    mov ebp, esp

    ; 定义局部变量:
    ; - buffer:存最终的前缀+计算机名(100字节足够)
    ; - tempCompName:临时存获取到的计算机名(80字节)
    ; - compNameSize:GetComputerName的长度参数(输入输出)
    LOCAL buffer[100]:BYTE
    LOCAL tempCompName[80]:BYTE
    LOCAL compNameSize:DWORD

    ; 第一步:把前缀复制到buffer
    INVOKE lstrcpy, ADDR buffer, ADDR szPrefix

    ; 第二步:调用GetComputerName获取计算机名到临时缓冲区
    mov compNameSize, 80  ; 传入缓冲区最大长度(不含NULL)
    INVOKE GetComputerNameA, ADDR tempCompName, ADDR compNameSize

    ; 第三步:把计算机名追加到buffer的前缀后面
    INVOKE lstrcat, ADDR buffer, ADDR tempCompName

    ; 现在buffer里就是带前缀的完整字符串,可以传给TCP发送逻辑了
    ; ... 这里写你的TCP发送代码

    ; 清理栈帧返回
    mov esp, ebp
    pop ebp
    ret
main endp
end main

三、关于“把预定义字符串存入局部变量/寄存器”的细节

  • 存入局部变量:上面用lstrcpy是最省心的方式。如果非要手动复制,就用esi指向.data段的前缀,edi指向栈上的buffer,然后lodsb+stosb循环,直到复制到NULL终止符。
  • 存入寄存器:寄存器是32位的,只能存最多4字节的短字符串,比如要存"Name",可以用mov eax, 0x656d614E(注意x86是小端字节序,所以实际内存里是4E 61 6D 65,对应"Name")。但长字符串肯定要存在内存(局部变量)里,寄存器放不下。

四、额外注意事项

  • 一定要用INVOKE指令调用API,MASM会自动处理stdcall的栈清理,避免手动add esp, 8出错。
  • GetComputerName的第三个参数是输入输出,调用后它会返回实际的计算机名长度(不含NULL),如果你的计算机名超长(超过80字节),可以适当调大临时缓冲区的大小。
  • 调试时可以用OllyDbg看栈上的buffer内容,确认字符串拼接是否正确,有没有越界。

内容的提问来源于stack exchange,提问作者StillWaters77

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:07:33