Причина, по которой вы получаете ошибку шины, заключается в том, что вы вызываете ret
в своем коде сборки. ret
заставляет программный элемент управления перейти на адрес возврата в верхней части стека, которым вы манипулируете, используя push
и pop
. Я настоятельно рекомендую посмотреть, что делает ret
в Справочнике по набору инструкций Intel.
Ниже приведен код, который я скомпилировал и успешно выполнил на iMac под управлением Mac OS X 10.6.7.
#include <stdio.h>
/*__declspec(naked)*/ void
doStuff(unsigned long int val, unsigned long int flags, unsigned char *result)
{
__asm
{
push eax
push ebx
push ecx
mov eax, dword ptr[ebp + 8] //val
mov ebx, dword ptr[ebp + 12] //flags
mov ecx, dword ptr[ebp + 16] //result
and eax, ebx
mov [ecx], eax
pop ecx
pop ebx
pop eax
}
}
int main(int argc, char *argv[])
{
unsigned long val = 0xAA00A1F2;
unsigned long flags = 0x00100002;
unsigned char result = 0x0;
doStuff(val, flags, &result);
printf("Result is: %2Xh\n", result);
return 0;
}
Заметные изменения:
- Снятие
ret
во встроенной сборке
- Использование регистра
ebp
вместо esp
для ссылки на параметры doStuff
- Изменение
flags
на 0x00100002
Изменение (1) исправляет ошибку шины, (2) делает ссылку на параметры несколько более согласованной, а (3) это просто быстрый способ убедиться, что функция работает должным образом.
Наконец, я настоятельно рекомендую вам ознакомиться с отладчиком GNU, GDB, если вы этого еще не сделали. Вы можете найти больше информации об этом на странице проекта http://www.gnu.org/software/gdb/, а также информацию о реализации Mac и учебном руководстве по http://developer.apple.com/library/mac/#documentation/DeveloperTools/gdb/gdb/gdb_toc.html.
РЕДАКТИРОВАТЬ: Добавлена основная информация / ссылка на GDB,