MASM ул и субстра? - PullRequest
       3

MASM ул и субстра?

2 голосов
/ 06 октября 2010

В настоящее время я пишу бот irc в asm. Я уже делал это однажды в C ++, поэтому я знаю, как решить большинство проблем, с которыми я сталкиваюсь, но мне нужна функция substr () [*], подобная той, что была в C ++.,Мне нужна функция substr для получения имени сервера из запроса PING, чтобы я мог ответить соответствующим ответом PONG

Но я не знаю, как реализовать его в MASM, я слышал о том, что называется макроассемблированием, этокажется, что substr часто используется в этих функциях

Кто-нибудь знает, как я могу заставить мою функцию substr работать

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

Вот как яиспользуйте функцию substr () в 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!
}

Где данные - это строка, содержащая всю информацию, которую сервер посылает мне, а SCHiMBot - это класс, который я использую для общения с сервером. Этот код c & p'edпрямо из бота я кодировал, так что должно быть безупречно

Ответы [ 2 ]

1 голос
/ 07 октября 2010

Это действительно не так просто ответить, как может показаться на первый взгляд. Проблема довольно проста: такая функция, как 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
0 голосов
/ 06 октября 2010
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!
    }
}
...