2013-09-29 27 views
3

我有以下汇编代码(NASM)大会目标C类的alloc错误

global _main 

extern _sizeof 
extern _printf 
extern _objc_msgSend 
extern _objc_getClass 
extern _sel_registerName 

SECTION .data 

alert_text : db "NSAlert", 0 
alloc_sel : db "alloc", 0 
init_sel : dw "init", 0 

alert_class: resb 4 

SECTION .text 
_main: 

; get the class 
sub esp, 8 
push alert_text 
call _objc_getClass 
add esp, 12 

; save class 
mov dword [alert_class], eax 

; get alloc selector 
sub esp, 8 
push alloc_sel 
call _sel_registerName 
add esp, 12 

; allocate it 
sub esp, 4 
push alloc_sel 
; push alert class 
mov eax, dword [alert_class] 
push eax 

call _objc_msgSend 
add esp, 12 

mov eax, 0 
ret 

我然后用

$ nasm -fmacho UI.asm -o UI.o 
UI.asm:83: warning: uninitialised space declared in __data section: zeroing 
$ ld UI.o -macosx_version_min 10.8 -lSystem -framework CoreFoundation -framework AppKit -o UI 

组装它当我运行它,我得到

$ ./UI 
2013-09-28 22:29:31.110 UI[60688:707] *** NSForwarding: warning: selector (0x201c) for message 'alloc' does not match selector known to Objective C runtime (0x97ee8e93)-- abort 
2013-09-28 22:29:31.112 UI[60688:707] +[NSAlert alloc]: unrecognized selector sent to class 0xacb12514 
2013-09-28 22:29:31.112 UI[60688:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSAlert alloc]: unrecognized selector sent to class 0xacb12514' 
*** Call stack at first throw: 
(
    0 CoreFoundation      0x99b28e8b __raiseError + 219 
    1 libobjc.A.dylib      0x9617e52e objc_exception_throw + 230 
    2 CoreFoundation      0x99b2c8ed +[NSObject(NSObject) doesNotRecognizeSelector:] + 253 
    3 CoreFoundation      0x99a74e87 ___forwarding___ + 487 
    4 CoreFoundation      0x99a74c32 _CF_forwarding_prep_0 + 50 
    5 UI         0x00001ff1 main + 71 
) 
Trace/BPT trap: 5 

我无法弄清楚为什么它不起作用,这与保存警报类有关吗?

+0

应该不重要Mac的文档说的是相同的实现和sel_register更好,sel_getUid只是为了兼容,但我会尝试 – Zimm3r

+0

不会有同样的错误将其更改为sel_getUid没有帮助 – Zimm3r

+0

我不好,我想到了老ABI在哪里很重要。 –

回答

5

据我所知(我承认我不是装配专家),你正在注册选择器,但从不使用它。

sel_registerName声明如下:

SEL sel_registerName(const char *str); 

的幕后,C-字符串实习,和一个新的指针(从选择的哈希表)返回,然后必须用于未来方法调用,如下所示:

SEL alloc_sel = sel_registerName("alloc"); 
id newObject = objc_msgSend(target_class, alloc_sel); 

有关此问题的原因,请参阅Why can't we use C-strings as SELs?

+0

哇,谢谢我甚至没有试图这样做(我正在调用sel_registerName)只是再次推动了字符串而不是eax。 – Zimm3r

+0

适合所有人,我向你保证。 –