2

私は現在、asmでircボットをコーディングしています。これは、C ++で一度行ったことがあるので、発生するほとんどの問題を解決する方法を知っていますが、C ++で見られるようなsubstr()[*]関数が必要です。対応するPONG応答で応答できるように、PING要求からサーバー名を受け取るsubstr関数が必要です

しかし、MASMでそれを実行する方法がわかりません。マクロアセンブルと呼ばれるものを聞いたのですが、これらの関数では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はサーバーとの通信に使用するクラスです。このコードは、コード化したボットから直接c&pされているため、完璧である必要があります。

4

2 に答える 2

1

これは、最初に思われるほど簡単に答えることはできません。問題は非常に単純です: のような関数substrは実際には単独では存在しません。これは文字列ライブラリの一部であり、それを有用なものにするためには、少なくともライブラリ全体がどのように適合するか、どのように適合するかをスケッチする必要があります。データなどを表します。つまり、文字列を作成しますが、そのためには文字列substr何であるかを決定する必要があります。

その問題を回避するために、私はあなたが実際に尋ねたことを無視して、アセンブリ言語により適したやや単純な答えを出します。本当に必要なのは、データの 1 つのバッファーから開始し、そのバッファーでいくつかの "マーカー" を見つけて、それらのマーカーの間にあるものを別のバッファーの指定された位置にコピーすることです。まず、「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 に答える