Регистрация Главная Сообщество
Сообщения за день Справка Регистрация

__cdecl, variable arguments и все что с ними связано

-

Вопросы и ответы, обсуждения

- Ваши вопросы по C/C++ только в данном разделе

Ответ
 
Опции темы
Старый 05.03.2013, 10:17   #1
 Сержант
Аватар для Yukikaze
 
Yukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядом
Регистрация: 01.10.2011
Сообщений: 128
Популярность: 5723
Сказал(а) спасибо: 25
Поблагодарили 174 раз(а) в 105 сообщениях
 
По умолчанию __cdecl, variable arguments и все что с ними связано

Знаю, что это последнее место где стоит задавать подобный вопрос, но я наверное конченый оптимист.
Есть функция со следующей сигнатурой
Код:
void __cdecl foo(void*, char*,...)
мне нужно из функции bar с такой же сигнатурой вызвать foo, собственно делаю это так
Код:
void __cdecl bar(void* obj, char* format,...)
{
    va_list args;
    va_start(args, format);
    foo(obj, format, args);
}
с тем же самым printf'ом это срабатывает, но здесь нет
если оригинальная функция имеет вид foo(obj, format, 0x1, 0x2, 0x3) то ее асемблерный вариант выглядит так:
Код:
push 0x3
push 0x2
push 0x1
push format
push obj
call foo
а если вызывать ее из bar то получается
Код:
push args
push format
push obj
call foo
в args помещается указатель на 3 значения в стеке, из за чего функция отказывается корректно работать.
Сразу отмечу, что к исходникам функции foo я доступа не имею.

Вот такая вот хитрая проблема
________________
Talk is cheap. Show me the code
— Linus Torvalds
  Ответить с цитированием
Старый 06.03.2013, 10:53   #2
Super Moderator
 Сержант
Аватар для Рэйзор
 
Рэйзор сломал счётчик популярности :(Рэйзор сломал счётчик популярности :(Рэйзор сломал счётчик популярности :(Рэйзор сломал счётчик популярности :(Рэйзор сломал счётчик популярности :(Рэйзор сломал счётчик популярности :(Рэйзор сломал счётчик популярности :(Рэйзор сломал счётчик популярности :(Рэйзор сломал счётчик популярности :(Рэйзор сломал счётчик популярности :(Рэйзор сломал счётчик популярности :(
Регистрация: 20.07.2010
Сообщений: 137
Популярность: 26409
Сказал(а) спасибо: 52
Поблагодарили 566 раз(а) в 197 сообщениях
 
По умолчанию Re: __cdecl, variable arguments и все что с ними связано

я конечно мб не особо вник, но
у тебя же директива __cdecl, значит параметры будут как на чистом сишнике передаваться в обратном порядке, что видно в ее ассемблерном варианте.
Как я понял, в args указатель идет на стек, где все лежит в порядке 0x1 0x2 0x3.
Когда ты вызываешь foo, в стек вызова все складывается в следующем порядке (формально естественно, ибо мы как бы расписываем push args):
push 0x1
push 0x2
push 0x3
push format
push obj
call foo
потому как из стека все забирается по правилу LIFO (Last in, First out)
а должно
push 0x3
push 0x2
push 0x1
push format
push obj
call foo
в этом, видимо, и есть проблема

Последний раз редактировалось Рэйзор; 06.03.2013 в 11:00.
  Ответить с цитированием
Старый 07.03.2013, 09:37   #3
 Сержант
Аватар для Yukikaze
 
Yukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядом
Регистрация: 01.10.2011
Сообщений: 128
Популярность: 5723
Сказал(а) спасибо: 25
Поблагодарили 174 раз(а) в 105 сообщениях
 
По умолчанию Re: __cdecl, variable arguments и все что с ними связано

кстати я таки разобрался, всего то нужно было поправить регистры
Код:
void _cdecl bar(void* obj, char* format, ...)
{
	va_list args;
	va_start(args, format);
        //тут вызывается функция...
        //и приходится востанавливать после нее регистры
	__asm mov esp,ebp
	__asm pop ebp
	__asm jmp [foo] //Верхом на шлюхах прямо в рай!
}
________________
Talk is cheap. Show me the code
— Linus Torvalds
  Ответить с цитированием
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ярмарка и всё, что с ней связано! BermuD56946 Общение и обсуждение Perfect World 1 17.02.2013 20:02
evSpeed - variable speedhack for Cataclysm 4.1.0.14007 trone Читы, баги и статьи по WoW 5 20.06.2011 01:52
[Помогите!] Пинг или что с ним связано decoy54321 Общение и обсуждение Counter-Strike 6 03.01.2011 21:52
[Обсуждение] С чем это связано? Dimon1987 Общение и обсуждение 1 27.08.2010 18:02

Заявление об ответственности / Список мошенников

Часовой пояс GMT +4, время: 15:45.

Пишите нам: [email protected]
Copyright © 2024 vBulletin Solutions, Inc.
Translate: zCarot. Webdesign by DevArt (Fox)
G-gaMe! Team production | Since 2008
Hosted by GShost.net