2

我目前正在用 asm 编写一个 irc 机器人,我已经在 C++ 中做过一次,所以我知道如何解决我遇到的大多数问题,但我需要一个 substr()[*] 函数,就像在 C++ 中看到的那样。我需要 substr 函数从 PING 请求中接收服务器名称,以便我可以使用相应的 PONG 响应进行响应

但是我不知道如何在MASM中实现它,我听说过一种叫做macroassemble的东西,似乎substr经常用在那些函数中

有谁知道我怎样才能让我的 substr 函数工作

[*] string substr ( size_t pos = 0, size_t n = npos )

这就是我在 C++ 中使用 substr() 函数的方式:

if(data.find("PING :") != std::string::npos){
string pong = "PONG :" + data.substr(  (data.find_last_of(":")+1), (data.find_last_of("\r")-1)  );
SCHiMBot.Pong(pong);   // Keep the connection alive!
}

其中 data 是一个字符串,包含服务器发送给我的所有信息,SCHiMBot 是我用来与服务器对话的类 此代码是直接从我编写的机器人中复制出来的,所以它应该是完美的

4

2 回答 2

1

这真的不像最初看起来那么容易回答。问题很简单:像这样的函数substr并不是真正孤立存在的——它是字符串库的一部分,为了使它有用,你至少需要勾勒出整个库是如何组合在一起的,如何您代表您的数据等。即,substr创建一个字符串,但要这样做,您需要确定什么是字符串

为了避免这个问题,我将忽略您实际提出的问题,并给出一个更适合汇编语言的更简单的答案。您真正需要的是从一个数据缓冲区开始,在该缓冲区中找到几个“标记”,然后将这些标记之间的内容复制到另一个缓冲区中的指定位置。首先我们需要代码来执行“find_last”:

; expects: 
; ESI = address of buffer
; ECX = length of data in buffer
; AH =  character to find
; returns:
; ESI = position of item
;
find_last proc 
    mov al, [esi+ecx]
    cmp ah, al
    loopnz  find_last
    ret
find_last endp

现在要将子字符串复制到传输缓冲区,我们执行以下操作:

CR = 13

copy_substr proc
    mov esi, offset read_buffer
    mov ecx, bytes_read
    mov ah, CR
    call find_last   ; find the carriage-return
    mov edx, esi     ; save its position

    mov esi, offset read_buffer
    mov ecx, bytes_read
    mov ah, ':'
    call find_last   ; find the colon
    inc esi          ; point to character following colon
    sub edx, esi     ; get distance from colon+1 to CR
    mov ecx, edx   

    ; Now: ESI = address following ':'
    ;      ECX = distance to CR

    mov edi, (offset trans_buffer) + prefix_length
    rep movsb         ; copy the data
    ret
copy_substr endp
于 2010-10-06T21:04:02.140 回答
0
data.substr(  (data.find_last_of(":")+1)

的第一个参数substr是起始位置。如果是传递字符串最后一个元素的值,则会抛出 out_of_range 异常。您应该确认这没有发生。

if(data.find("PING :") != std::string::npos)
{
    size_t s1 = data.find_last_of(":");
    size_t s2 = data.find_last_of("\r");

    if (s1 != string::npos &&
        s2 != string::npos &&
        s1+1 < data.size())
    {
        string pong = "PONG :" + data.substr(s1+1, s2-1);
        SCHiMBot.Pong(pong);   // Keep the connection alive!
    }
}
于 2010-10-06T15:57:02.397 回答