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