objective-c - 程序集 Objective-C 类分配错误

标签 objective-c macos assembly objective-c-runtime

我有以下汇编代码(NASM)

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

我不明白为什么它不起作用,是否与保存警报类有关?

最佳答案

据我所知(诚然我不是汇编专家),您正在注册选择器,但永远不要使用它。

sel_registerName 声明如下:

SEL sel_registerName(const char *str);

在幕后,c 字符串被驻留,并返回一个新指针(来自选择器的哈希表),然后必须将其用于 future 的方法调用,如下所示:

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

参见 Why can't we use C-strings as SELs?至于这个问题的原因。

关于objective-c - 程序集 Objective-C 类分配错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19073816/

相关文章:

macos - 如何在 Sublime Text (OSX) 中恢复我的输出面板?

MacOS GameKit 排行榜无法加载,并出现 App "does not support leaderboards"错误

c - 缓冲区溢出跳转到禁用的功能

php - AFNetworking 发布错误

iphone - iOS 上 IPv6 的 DNS 解析仅同步?

objective-c - 垂直拼接/合成多个图像并保存为一个图像(iOS,objective-c)

html - Safari 浏览器中的 `height: intrinsic` 是什么?

assembly - 关于 8086 程序集的 DB 和 DUP 指令

c - execve x86 - 段错误

ios - AFNetworking请求操作-创建 channel /瓶颈队列单例