views:

111

answers:

2

Hello everybody, I'm currently coding an irc bot in asm I have already done this once in C++, so I know how to solve most problems I encounter, but I need a substr()[*] function like the one seen in C++. I need the substr fucntion to receive the server name from a PING request so I can respond with the corresponding PONG response

But I don't know how to implent it in MASM, I heard of something called macroassembling, It seems substr is often used in those funcions

Does anyone have any idea how I can get my substr function to work

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

This is how I use the substr() funcion in C++:

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!
}

Where data is a string holding all the information the server sends me, and SCHiMBot is a class I use to talk with the server This code is c&p'ed directly out of a bot I coded, so it should be flawless

A: 
data.substr(  (data.find_last_of(":")+1)

The first parameter of substr is the starting position. If it is a value passed the last element of the string, out_of_range exception will be thrown. You should verify that this is not happening.

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!
    }
}
Donotalo
I think you've misunderstood my question, I'm trying to reproduce the same effect in asm code as in what happens in the C++ (The data will never end in the middle of the PING : string, since there's always data following, but I'll keep the comment in mind)
Rick
i reread your question and i really misunderstood your problem. sorry for that. i thought this version of C+ you posted is not working.
Donotalo
+1  A: 

This really isn't nearly as easy to answer is it might initially seem. The problem is pretty simple: a function like substr doesn't really exist in isolation -- it's part of a string library, and to make it useful, you just about need to at least sketch out how the library as a whole fits together, how you represent your data, etc. I.e., substr creates a string, but to do so you need to decide what a string is.

To avoid that problem, I'm going to sort of ignore what you actually asked, and give a somewhat simpler answer that's more suited to assembly language. What you really need is to start with one buffer of data, find a couple of "markers" in that buffer, and copy what's in between those markers to a designated position in another buffer. First we need the code to do the "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

Now to copy the substring to the transmission buffer, we do something like this:

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
Jerry Coffin
Are you missing a couple of `ret` instructions?
spong
@spong: Not anymore! Thanks for reminding me -- it's obviously been a while since I did much coding in assembly language.
Jerry Coffin
Thank you, I will see if I can get this to work (I'm new to asm, and while I can use fucntions and check for errors, using the registers is still hard)
Rick
What do I need to put for prefix_length??
Rick
It looks like it should be 6 (the length of "PONG :"). I.e., `trans_buffer` points at the transmit buffer with "PONG :" already there, and `prefix_length` is how much is already used by the "PONG :".
Jerry Coffin
I'm having difficulties testing your code, because I have no way to compare strings I'm currently doing it like this but I don't know if its correct: mov edx, offset buff cmp edx,"P"
Rick