блок x86 на Mac

Когда вы объявляете ссылочную переменную (т. е. объект), вы действительно создаете указатель на объект. Рассмотрим следующий код, в котором вы объявляете переменную примитивного типа int:

int x;
x = 10;

В этом примере переменная x является int, и Java инициализирует ее для 0. Когда вы назначаете его 10 во второй строке, ваше значение 10 записывается в ячейку памяти, на которую указывает x.

Но когда вы пытаетесь объявить ссылочный тип, произойдет что-то другое. Возьмите следующий код:

Integer num;
num = new Integer(10);

Первая строка объявляет переменную с именем num, но она не содержит примитивного значения. Вместо этого он содержит указатель (потому что тип Integer является ссылочным типом). Поскольку вы еще не указали, что указать на Java, он устанавливает значение null, что означает «Я ничего не указываю».

Во второй строке ключевое слово new используется для создания экземпляра (или создания ) объекту типа Integer и переменной указателя num присваивается этот объект. Теперь вы можете ссылаться на объект, используя оператор разыменования . (точка).

Exception, о котором вы просили, возникает, когда вы объявляете переменную, но не создавали объект. Если вы попытаетесь разыменовать num. Перед созданием объекта вы получите NullPointerException. В самых тривиальных случаях компилятор поймает проблему и сообщит вам, что «num не может быть инициализирован», но иногда вы пишете код, который непосредственно не создает объект.

Например, вы можете имеют следующий метод:

public void doSomething(SomeObject obj) {
   //do something to obj
}

В этом случае вы не создаете объект obj, скорее предполагая, что он был создан до вызова метода doSomething. К сожалению, этот метод можно вызвать следующим образом:

doSomething(null);

В этом случае obj имеет значение null. Если метод предназначен для того, чтобы что-то сделать для переданного объекта, целесообразно бросить NullPointerException, потому что это ошибка программиста, и программисту понадобится эта информация для целей отладки.

Альтернативно, там могут быть случаи, когда цель метода заключается не только в том, чтобы работать с переданным в объекте, и поэтому нулевой параметр может быть приемлемым. В этом случае вам нужно будет проверить нулевой параметр и вести себя по-другому. Вы также должны объяснить это в документации. Например, doSomething может быть записано как:

/**
  * @param obj An optional foo for ____. May be null, in which case 
  *  the result will be ____.
  */
public void doSomething(SomeObject obj) {
    if(obj != null) {
       //do something
    } else {
       //do something else
    }
}

Наконец, Как определить исключение & amp; причина использования Трассировки стека

57
задан Scath 13 December 2017 в 16:11
поделиться

5 ответов

После установки любой версии XCode, предназначающегося для основанного на Intel Macs, необходимо быть в состоянии записать ассемблерный код. XCode является комплектом инструментов, только один из которых является IDE, таким образом, Вы не должны использовать его, если Вы не хотите. (Однако если существуют определенные вещи, Вы находите неуклюжими, зарегистрируйте ошибку в генератор отчетов ошибки Apple - каждая ошибка переходит к разработке.), Кроме того, устанавливание XCode установит и Ассемблер Netwide (NASM) и Ассемблер GNU (GAS); это позволит Вам использовать любой синтаксис блока, которым Вы являетесь самыми довольными.

Вы также захотите смотреть на Компилятор & Отлаживающие Руководства , потому что те документируют соглашения о вызовах, используемые для различной архитектуры, на которой Mac OS X работает, а также как двоичный формат и загрузчик работают. IA-32 (x86-32) соглашения о вызовах в особенности может немного отличаться от того, к чему Вы привыкли.

Другая вещь иметь в виду состоит в том, что интерфейс системного вызова на Mac OS X отличается от того, к чему Вы могли бы привыкнуть на DOS/Windows, Linux или других разновидностях BSD. Системные вызовы не считают стабильным API на Mac OS X; вместо этого, Вы всегда проходите libSystem. Это гарантирует запись кода, это портативно от одного выпуска ОС к следующему.

Наконец, имейте в виду, что Mac OS X натыкается на довольно огромное количество аппаратных средств - все от 32-разрядного Базового Сингла до высокопроизводительного четырехъядерного Xeon. Путем кодирования в блоке Вы не могли бы оптимизировать столько, сколько Вы думаете; то, что оптимально на одной машине, может быть прескверным на другом. Apple регулярно измеряет свои компиляторы и настраивает их вывод с "-OS" флаг оптимизации, чтобы быть достойной через его строку, и существуют обширные vector/matrix-processing библиотеки, которыми можно пользоваться для получения высокой производительности с настроенными на руку определенными для ЦП реализациями.

Движение к блоку для забавы является большим. Движение к блоку для скорости не для слабонервных в эти дни.

73
ответ дан ΦXocę 웃 Пepeúpa ツ 24 November 2019 в 19:27
поделиться

Как указано прежде, не используйте syscall. Можно использовать вызовы стандартной библиотеки для C хотя, но знать что стек MUST быть 16 байтов, выровненных на вызов функции ABI Apple IA32.

, Если Вы не выравниваете стек, Ваша программа откажет в __dyld_misaligned_stack_error, когда Вы позвоните в любую из библиотек или платформ.

следующий отрывок собирается и работает на моей системе:

; File: hello.asm
; Build: nasm -f macho hello.asm && gcc -o hello hello.o

SECTION .rodata
hello.msg db 'Hello, World!',0x0a,0x00

SECTION .text

extern _printf ; could also use _puts...
GLOBAL _main

; aligns esp to 16 bytes in preparation for calling a C library function
; arg is number of bytes to pad for function arguments, this should be a multiple of 16
; unless you are using push/pop to load args
%macro clib_prolog 1
    mov ebx, esp        ; remember current esp
    and esp, 0xFFFFFFF0 ; align to next 16 byte boundary (could be zero offset!)
    sub esp, 12         ; skip ahead 12 so we can store original esp
    push ebx            ; store esp (16 bytes aligned again)
    sub esp, %1         ; pad for arguments (make conditional?)
%endmacro

; arg must match most recent call to clib_prolog
%macro clib_epilog 1
    add esp, %1         ; remove arg padding
    pop ebx             ; get original esp
    mov esp, ebx        ; restore
%endmacro

_main:
    ; set up stack frame
    push ebp
    mov ebp, esp
    push ebx

    clib_prolog 16
    mov dword [esp], hello.msg
    call _printf
    ; can make more clib calls here...
    clib_epilog 16

    ; tear down stack frame
    pop ebx
    mov esp, ebp
    pop ebp
    mov eax, 0          ; set return code
    ret
29
ответ дан N3dst4 24 November 2019 в 19:27
поделиться

кроме того, на Intel Macs, я могу использовать универсальный x86 asm? или есть ли измененная система команд? Любая информация о сообщении блок Intel Mac помогает.

Это - та же система команд; это - те же микросхемы.

4
ответ дан Josh 24 November 2019 в 19:27
поделиться

Функции, доступные использованию, зависят от Вашего процессора. Apple использует тот же материал Intel в качестве всех других. Таким образом да, универсальный x86 должен быть прекрасным (предположение, что Вы не находитесь на PPC: D).

, Насколько инструменты идут, я думаю, что Ваш лучший выбор является хорошим текстовым редактором, который 'понимает' блок.

1
ответ дан Bernard 24 November 2019 в 19:27
поделиться

Забудьте о нахождении, что IDE пишет/выполняет/компилирует ассемблер на Mac, Но, помнит, что Mac является UNIX. См. http://asm.sourceforge.net/articles/linasm.html . Достойное руководство (хотя короткий) к рабочему ассемблеру через GCC на Linux. Можно подражать этому. Macs используют процессоры Intel, таким образом, Вы хотите посмотреть на синтаксис Intel.

0
ответ дан Stephen Cox 24 November 2019 в 19:27
поделиться