Общие сведения о соглашениях ABI ARM32Overview of ARM32 ABI Conventions

Двоичный интерфейс приложения (ABI) для кода, скомпилированного для Windows на процессорах ARM, основан на стандартном встроенном двоичном интерфейсе приложения ARM.The application binary interface (ABI) for code compiled for Windows on ARM processors is based on the standard ARM EABI. В этой статье указаны различия между системой Windows на устройствах ARM и стандартной системой.This article highlights key differences between Windows on ARM and the standard. В этом документе рассматривается ABI ARM32.This document covers the ARM32 ABI. Дополнительные сведения об интерфейсе ABI ARM64 см. в статье Общие сведения о соглашениях ABI ARM64.For information about the ARM64 ABI, see Overview of ARM64 ABI conventions. Дополнительные сведения о стандартном встроенном двоичном интерфейсе приложения ARM см. в статье Двоичный интерфейс приложения для архитектуры ARM (внешняя ссылка).For more information about the standard ARM EABI, see Application Binary Interface (ABI) for the ARM Architecture (external link).

Основные требованияBase Requirements

Система Windows на ARM всегда предполагает, что она выполняется в архитектуре ARMv7.Windows on ARM presumes that it is running on an ARMv7 architecture at all times. В оборудовании должна быть реализована поддержка вычислений с плавающей запятой в форме VFPv3-D32 или более поздней версии.Floating-point support in the form of VFPv3-D32 or later must be present in hardware. Технология VFP должна поддерживать форматы с плавающей запятой одиночной и двойной точности на оборудовании.The VFP must support both single-precision and double-precision floating-point in hardware. Среда выполнения Windows не поддерживает эмуляцию вычислений с плавающей запятой для выполнения на оборудовании без VFP.The Windows runtime does not support emulation of floating-point to enable running on non-VFP hardware.

В оборудовании также должна быть реализована поддержка усовершенствованных расширений SIMD (NEON), куда входят как целочисленные операции, так и операции с плавающей запятой.Advanced SIMD Extensions (NEON) support—this includes both integer and floating-point operations—must also be present in hardware. Поддержка эмуляции во время выполнения отсутствует.No run-time support for emulation is provided.

Наличие поддержки деления целых чисел (UDIV/SDIV) настоятельно рекомендуется, но не является обязательным.Integer divide support (UDIV/SDIV) is strongly recommended but not required. Платформы без поддержки деления целых чисел могут иметь сниженную производительность, так как эти операции требуется отследить и по возможности исправить.Platforms that lack integer divide support may incur a performance penalty because these operations have to be trapped and possibly patched.

Порядок байтовEndianness

Windows на ARM выполняется в режиме с прямым порядком байтов.Windows on ARM executes in little-endian mode. Как компилятор MSVC, так и среда выполнения Windows всегда ожидают данные с прямым порядком байтов.Both the MSVC compiler and the Windows runtime expect little-endian data at all times. Хотя инструкция SETEND в архитектуре набора инструкций (ISA) ARM позволяет даже коду пользовательского режима изменять текущий порядок байтов, поступать так не рекомендуется, так как это опасно для приложения.Although the SETEND instruction in the ARM instruction set architecture (ISA) allows even user-mode code to change the current endianness, doing so is discouraged because it's dangerous for an application. Если в режиме с обратным порядком байтов возникает исключение, работа становится непредсказуемой, что может привести к сбою приложения в пользовательском режиме или к возникновению критической ошибки в режиме ядра.If an exception is generated in big-endian mode, the behavior is unpredictable and may lead to an application fault in user mode, or a bugcheck in kernel mode.

ВыравниваниеAlignment

Хотя Windows позволяет оборудованию ARM незаметно обрабатывать невыровненные обращения к целым числам, в некоторых ситуациях все равно могут происходить сбои выравнивания.Although Windows enables the ARM hardware to handle misaligned integer accesses transparently, alignment faults still may be generated in some situations. Выполняйте следующие правила по выравниванию.Follow these rules for alignment:

  • Загрузки и сохранения целого числа размером в полслова (16 бит) и полное слово (32 бита) выравнивать не требуется.Half-word-sized (16-bit) and word-sized (32-bit) integer loads and stores do not have to be aligned. Оборудование само эффективно и легко обрабатывает их.The hardware handles them efficiently and transparently.

  • Загрузки и сохранения с плавающей запятой следует выравнивать.Floating-point loads and stores should be aligned. Ядро прозрачно обрабатывает невыровненные загрузки и сохранения, однако на это расходуются значительные ресурсы.The kernel handles unaligned loads and stores transparently, but with significant overhead.

  • Загрузку и сохранение двойных (LDRD/STRD) и множественных (LDM/STM) операций следует выравнивать.Load or store double (LDRD/STRD) and multiple (LDM/STM) operations should be aligned. Ядро прозрачно обрабатывает большинство из них, однако на это расходуются значительные ресурсы.The kernel handles most of them transparently, but with significant overhead.

  • Все некэшированные обращения к памяти следует выравнивать, даже при обращении к целым числам.All uncached memory accesses must be aligned, even for integer accesses. Невыровненные обращения вызывают сбой выравнивания.Unaligned accesses cause an alignment fault.

Набор инструкцийInstruction Set

Набор инструкций для Windows на ARM ограничен исключительно режимом Thumb-2.The instruction set for Windows on ARM is strictly limited to Thumb-2. Весь код, выполняемый на этой платформе, должен запускаться и оставаться в режиме Thumb на протяжении всего времени.All code executed on this platform is expected to start and remain in Thumb mode at all times. Попытка переключиться на устаревший набор инструкций ARM может оказаться успешной, однако в этом случае все возникающие исключения или прерывания могут привести к сбою приложения в пользовательском режиме или к возникновению критической ошибки в режиме ядра.An attempt to switch into the legacy ARM instruction set may succeed, but if it does, any exceptions or interrupts that occur may lead to an application fault in user mode, or a bugcheck in kernel mode.

Побочный эффект этого требования заключается в том, что все указатели кода должны иметь заданный младший бит.A side-effect of this requirement is that all code pointers must have the low bit set. В этом случае при их загрузке и ветвлении через BLX или BX процессор остается в режиме Thumb и не пытается выполнить целевой код как 32-разрядные инструкции ARM.This is so that when they are loaded and branched to via BLX or BX, the processor will remain in Thumb mode and not try to execute the target code as 32-bit ARM instructions.

Инструкции ITIT Instructions

Использование инструкций IT в коде Thumb-2 запрещено, кроме описанных ниже случаев.The use of IT instructions in Thumb-2 code is disallowed except for these specific cases:

  • Инструкцию IT можно использовать только для изменения одной целевой инструкции.The IT instruction can only be used to modify one target instruction.

  • Целевая инструкция должна быть 16-разрядной инструкцией.The target instruction must be a 16-bit instruction.

  • Целевая инструкция должна относиться к одному из следующих типов.The target instruction must be one of these:

    16-разрядные коды операций16-Bit Opcodes КлассClass ОграниченияRestrictions
    MOV, MVNMOV, MVN ПеремещениеMove Rm != PC, Rd != PCRm != PC, Rd != PC
    LDR, LDR[S]B, LDR[S]HLDR, LDR[S]B, LDR[S]H Загрузка из памятиLoad from memory Но не формы литерала LDRBut not LDR literal forms
    STR, STRB, STRHSTR, STRB, STRH Сохранение в памятьStore to memory
    ADD, ADC, RSB, SBC, SUBADD, ADC, RSB, SBC, SUB Сложение или вычитаниеAdd or subtract Но не формы ADD/SUB SP, SP, imm7But not ADD/SUB SP, SP, imm7 forms

    Rm != PC, Rdn != PC, Rdm != PCRm != PC, Rdn != PC, Rdm != PC
    CMP, CMNCMP, CMN СравнениеCompare Rm != PC, Rn != PCRm != PC, Rn != PC
    MULMUL MultiplyMultiply
    ASR, LSL, LSR, RORASR, LSL, LSR, ROR Сдвиг битовBit shift
    AND, BIC, EOR, ORR, TSTAND, BIC, EOR, ORR, TST Побитовая арифметикаBitwise arithmetic
    BXBX Ветвление для регистраBranch to register Rm != PCRm != PC

Хотя современные ЦП ARMv7 не могут сообщить об использовании запрещенных форм инструкций, будущие поколения ЦП получат такую возможность.Although current ARMv7 CPUs cannot report the use of disallowed instruction forms, future generations are expected to. При обнаружении этих форм любая использующая их программа будет завершена с исключением неопределенной инструкции.If these forms are detected, any program that uses them may be terminated with an undefined instruction exception.

Инструкции SDIV/UDIVSDIV/UDIV instructions

Использование инструкций деления целых чисел SDIV и UDIV полностью поддерживается даже на платформах, не имеющих собственного оборудования для их обработки.The use of integer divide instructions SDIV and UDIV is fully supported, even on platforms without native hardware to handle them. Нагрузка при операции деления с использованием SDIV или UDIV на процессоре Cortex-A9 составляет около 80 циклов без учета общего времени выполнения операции деления, которое составляет от 20 до 250 циклов в зависимости от входных данных.The overhead per SDIV or UDIV divide on a Cortex-A9 processor is approximately 80 cycles, in addition to the overall divide time of 20-250 cycles, depending on the inputs.

Целочисленные регистрыInteger registers

Процессор ARM поддерживает 16 целочисленных регистров.The ARM processor supports 16 integer registers:

РегистровоеRegister Переменный?Volatile? РольRole
r0r0 ПеременныйVolatile Параметр, результат, оперативный регистр 1Parameter, result, scratch register 1
r1r1 ПеременныйVolatile Параметр, результат, оперативный регистр 2Parameter, result, scratch register 2
r2r2 ПеременныйVolatile Параметр, оперативный регистр 3Parameter, scratch register 3
r3r3 ПеременныйVolatile Параметр, оперативный регистр 4Parameter, scratch register 4
r4r4 НеизменяемыйNon-volatile
r5r5 НеизменяемыйNon-volatile
r6r6 НеизменяемыйNon-volatile
r7r7 НеизменяемыйNon-volatile
r8r8 НеизменяемыйNon-volatile
r9r9 НеизменяемыйNon-volatile
r10r10 НеизменяемыйNon-volatile
r11r11 НеизменяемыйNon-volatile Указатель фреймаFrame pointer
r12r12 ПеременныйVolatile Оперативный регистр для вызова внутри процедурыIntra-procedure-call scratch register
r13 (SP)r13 (SP) НеизменяемыйNon-volatile Указатель стекаStack pointer
r14 (LR)r14 (LR) НеизменяемыйNon-volatile Регистр связиLink register
r15 (PC)r15 (PC) НеизменяемыйNon-volatile Счетчик командProgram counter

Сведения об использовании регистров параметра и возвращаемого значения см. в разделе "Передача параметров" этой статьи.For details about how to use the parameter and return value registers, see the Parameter Passing section in this article.

Windows использует r11 для быстрого прохода кадра стека.Windows uses r11 for fast-walking of the stack frame. Дополнительные сведения см. в разделе "Проверка стека".For more information, see the Stack Walking section. Из-за этого требования r11 всегда должен указывать на самое верхнее звено в цепочке.Because of this requirement, r11 must point to the topmost link in the chain at all times. Не используйте r11 для выполнения общих задач: ваш код не создаст правильные проверки стека во время анализа.Do not use r11 for general purposes—your code will not generate correct stack walks during analysis.

Регистры VFPVFP registers

Windows поддерживает только варианты ARM, имеющие поддержку сопроцессора VFPv3-D32.Windows only supports ARM variants that have VFPv3-D32 coprocessor support. Это означает, что регистры операций с плавающей запятой всегда присутствуют и могут использоваться для передачи параметров и что для использования доступен полный набор из 32 регистров.This means that floating-point registers are always present and can be relied on for parameter passing, and that the full set of 32 registers is available for use. Регистры VFP и их использование описаны в следующей таблице.The VFP registers and their usage are summarized in this table:

ОдиночныеSingles ДвойныеDoubles СчетверенныеQuads Переменный?Volatile? РольRole
s0—s3s0-s3 d0—d1d0-d1 q0q0 ПеременныйVolatile Параметры, результат, оперативный регистрParameters, result, scratch register
s4—s7s4-s7 d2—d3d2-d3 q1q1 ПеременныйVolatile Параметры, оперативный регистрParameters, scratch register
s8—s11s8-s11 d4—d5d4-d5 q2q2 ПеременныйVolatile Параметры, оперативный регистрParameters, scratch register
s12—s15s12-s15 d6—d7d6-d7 q3q3 ПеременныйVolatile Параметры, оперативный регистрParameters, scratch register
s16—s19s16-s19 d8—d9d8-d9 q4q4 НеизменяемыйNon-volatile
s20—s23s20-s23 d10—d11d10-d11 q5q5 НеизменяемыйNon-volatile
s24—s27s24-s27 d12—d13d12-d13 q6q6 НеизменяемыйNon-volatile
s28—s31s28-s31 d14—d15d14-d15 q7q7 НеизменяемыйNon-volatile
d16—d31d16-d31 q8—q15q8-q15 ПеременныйVolatile

В следующей таблице представлены битовые поля регистра управления и состояний для операций с плавающей точкой (FPSCR).The next table illustrates the floating-point status and control register (FPSCR) bitfields:

BitsBits ЗначениеMeaning Переменный?Volatile? РольRole
31—2831-28 NZCVNZCV ПеременныйVolatile Флаги состоянияStatus flags
2727 QCQC ПеременныйVolatile Совокупное насыщениеCumulative saturation
2626 AHPAHP НеизменяемыйNon-volatile Альтернативное управление с половинной точностьюAlternative half-precision control
2525 DNDN НеизменяемыйNon-volatile Управление режимом по умолчанию NaNDefault NaN mode control
2424 FZFZ НеизменяемыйNon-volatile Управление режимом обнуленияFlush-to-zero mode control
23—2223-22 RModeRMode НеизменяемыйNon-volatile Управление режимом округленияRounding mode control
21—2021-20 StrideStride НеизменяемыйNon-volatile Шаг вектора, должен всегда быть равен 0.Vector Stride, must always be 0
18—1618-16 LenLen НеизменяемыйNon-volatile Длина вектора, должен всегда быть равен 0.Vector Length, must always be 0
15, 12—815, 12-8 IDE, IXE и т. п.IDE, IXE, etc. НеизменяемыйNon-volatile Биты отслеживания исключения, должен всегда быть равен 0.Exception trap enable bits, must always be 0
7, 4—07, 4-0 IDC, IXC и т. п.IDC, IXC, etc. ПеременныйVolatile Совокупные флаги исключенияCumulative exception flags

Исключения для плавающей запятойFloating-point exceptions

Большинство оборудования ARM не поддерживает исключения для операций с плавающей запятой IEEE.Most ARM hardware does not support IEEE floating-point exceptions. На вариантах процессоров, имеющих аппаратные исключения для вычислений с плавающей запятой, ядро Windows автоматически перехватывает эти исключения и неявно отключает их в регистре FPSCR.On processor variants that do have hardware floating-point exceptions, the Windows kernel silently catches the exceptions and implicitly disables them in the FPSCR register. Так обеспечивается нормализованное поведение на вариантах процессоров.This ensures normalized behavior across processor variants. В противном случае код, разработанный на платформе без поддержки исключений, может получать непредвиденные исключения при выполнении на платформе с поддержкой исключений.Otherwise, code developed on a platform that doesn't have exception support could receive unexpected exceptions when it's running on a platform that has exception support.

Передача параметровParameter passing

Для функций без переменного числа аргументов двоичный интерфейс приложения Windows на ARM соответствует правилам ARM для передачи параметров, включая VFP и усовершенствованные расширения SIMD.For non-variadic functions, the Windows on ARM ABI follows the ARM rules for parameter passing—this includes the VFP and Advanced SIMD extensions. Эти правила соответствуют стандарту вызова процедур для архитектуры ARM совместно с расширениями VFP.These rules follow the Procedure Call Standard for the ARM Architecture, consolidated with the VFP extensions. По умолчанию в регистры передаются четыре первых целочисленных аргумента и до восьми аргументов с плавающей запятой или векторных аргументов; дополнительные аргументы передаются в стек.By default, the first four integer arguments and up to eight floating-point or vector arguments are passed in registers, and additional arguments are passed on the stack. Аргументы назначаются регистрам или стеку с помощью следующей процедуры.Arguments are assigned to registers or the stack by using this procedure:

Этап А. ИнициализацияStage A: Initialization

Инициализация выполняется только один раз перед началом обработки аргументов.Initialization is performed exactly once, before argument processing begins:

  1. Для номера следующего базового регистра (NCRN) устанавливается r0.The Next Core Register Number (NCRN) is set to r0.

  2. Регистры VFP помечаются как невыделенные.The VFP registers are marked as unallocated.

  3. Для адреса следующего помещенного в стек аргумента (NSAA) устанавливается текущий SP.The Next Stacked Argument Address (NSAA) is set to the current SP.

  4. Если вызывается функция, возвращающая результат в память, то адрес этого результата помещается в r0, а для NCRN устанавливается значение r1.If a function that returns a result in memory is called, then the address for the result is placed in r0 and the NCRN is set to r1.

Этап Б. Предварительное заполнение и расширение аргументовStage B: Pre-padding and extension of arguments

Для каждого имеющегося аргумента применяется первое соответствующее правило из следующего списка.For each argument in the list, the first matching rule from the following list is applied:

  1. Если аргумент имеет составной тип и его размер не может быть статически определен как вызывающим, так и вызываемым объектом, этот аргумент копируется в память и заменяется указателем для дальнейшего копирования.If the argument is a composite type whose size cannot be statically determined by both the caller and the callee, the argument is copied to memory and replaced by a pointer to the copy.

  2. Если аргумент имеет тип байта или 16-битного полуслова, то он расширяется нулем или знаком до полного 32-битного слова и считается 4-байтным аргументом.If the argument is a byte or 16-bit half-word, then it is zero-extended or sign-extended to a 32-bit full word and treated as a 4-byte argument.

  3. Если аргумент имеет составной тип, его размер округляется до ближайшего значения, кратного 4.If the argument is a composite type, its size is rounded up to the nearest multiple of 4.

Этап В. Назначение аргументов регистрам и стекуStage C: Assignment of arguments to registers and stack

Для каждого имеющегося аргумента по очереди применяются следующие правила, пока аргумент не будет назначен.For each argument in the list, the following rules are applied in turn until the argument has been allocated:

  1. Если аргумент имеет тип VFP и доступно достаточно последовательных невыделенных регистров VFP нужного типа, то аргумент назначается последовательности таких регистров с наименьшими номерами.If the argument is a VFP type and there are enough consecutive unallocated VFP registers of the appropriate type, then the argument is allocated to the lowest-numbered sequence of such registers.

  2. Если аргумент имеет тип VFP, все оставшиеся неназначенные регистры помечаются как недоступные.If the argument is a VFP type, all remaining unallocated registers are marked as unavailable. Адрес NSAA корректируется вверх до тех пор, пока не будет выровнен для данного типа аргумента, после чего аргумент копируется в стек по скорректированному NSAA.The NSAA is adjusted upwards until it is correctly aligned for the argument type and the argument is copied to the stack at the adjusted NSAA. После этого адрес NSAA увеличивается на размер аргумента.The NSAA is then incremented by the size of the argument.

  3. Если аргумент требует 8-байтового выравнивания, номер NCRN округляется до следующего четного номера регистра.If the argument requires 8-byte alignment, the NCRN is rounded up to the next even register number.

  4. Если размер аргумента в 32-разрядных словах превышает разность значений r4 и NCRN, этот аргумент копируется в базовые регистры, начиная с номера NCRN, при этом менее важные биты занимают регистры с меньшими номерами.If the size of the argument in 32-bit words is not more than r4 minus NCRN, the argument is copied into core registers, starting at the NCRN, with the least significant bits occupying the lower-numbered registers. Номер NCRN увеличивается на число использованных регистров.The NCRN is incremented by the number of registers used.

  5. Если номер NCRN меньше r4, а адрес NSAA равен SP, аргумент делится между базовыми регистрами и стеком.If the NCRN is less than r4 and the NSAA is equal to the SP, the argument is split between core registers and the stack. Первая часть аргумента копируется в базовые регистры, начиная с номера NCRN, и до r3 включительно.The first part of the argument is copied into the core registers, starting at the NCRN, up to and including r3. Оставшаяся часть аргумента копируется в стек, начиная с адреса NSAA.The remainder of the argument is copied onto the stack, starting at the NSAA. Номер NCRN задается равным r4, а адрес NSAA увеличивается на размер разности размера аргумента и числа переданных регистров.The NCRN is set to r4 and the NSAA is incremented by the size of the argument minus the amount passed in registers.

  6. Если аргумент требует 8-байтового выравнивания, адрес NSAA округляется до следующего выровненного по 8 байтам адреса.If the argument requires 8-byte alignment, the NSAA is rounded up to the next 8-byte aligned address.

  7. Аргумент копируется в память по адресу NSAA.The argument is copied into memory at the NSAA. Адрес NSAA увеличивается на размер аргумента.The NSAA is incremented by the size of the argument.

Регистры VFP не используются для функций с переменным числом аргументов, поэтому правила 1 и 2 этапа В игнорируются.The VFP registers are not used for variadic functions, and Stage C rules 1 and 2 are ignored. Это означает, что функция с переменным числом аргументов может начинаться с необязательной передачи {r0—r3}, чтобы добавить аргументы регистров перед дополнительными аргументами, переданными вызывающим объектом, а затем получить доступ ко всему списку аргументов прямо из стека.This means that a variadic function can begin with an optional push {r0-r3} to prepend the register arguments to any additional arguments passed by the caller, and then access the entire argument list directly from the stack.

Целочисленные значения возвращаются в r0 и при необходимости расширяются до r1 для 64-разрядных значений.Integer type values are returned in r0, optionally extended to r1 for 64-bit return values. Значения с плавающей запятой VFP/NEON или типом SIMD возвращаются в s0, d0 или q0.VFP/NEON floating-point or SIMD type values are returned in s0, d0, or q0, as appropriate.

СтекStack

Стек должен всегда оставаться выровненным по 4 байтам, а также он должен быть выровненным по 8 байтам на любой границе функции.The stack must remain 4-byte aligned at all times, and must be 8-byte aligned at any function boundary. Это необходимо для поддержки частого использования заблокированных операций с 64-разрядными переменными стека.This is required to support the frequent use of interlocked operations on 64-bit stack variables. Стандартный встроенный двоичный интерфейс приложения ARM требует, чтобы стек был выровнен по 8 байтам в любом общедоступном интерфейсе.The ARM EABI states that the stack is 8-byte aligned at any public interface. Для обеспечения согласованности двоичный интерфейс приложения Windows на ARM считает любую границу функции общедоступным интерфейсом.For consistency, the Windows on ARM ABI considers any function boundary to be a public interface.

Функции, которым требуется использовать указатель фрейма, например функции, вызывающие alloca или динамически изменяющие указатель стека, должны устанавливать этот указатель фрейма в r11 в прологе функции и оставлять его неизменным до эпилога.Functions that have to use a frame pointer—for example, functions that call alloca or that change the stack pointer dynamically—must set up the frame pointer in r11 in the function prologue and leave it unchanged until the epilogue. Функции, которым указатель фрейма не требуется, должны выполнять все обновления стека в прологе и оставлять указатель стека неизменным до эпилога.Functions that do not require a frame pointer must perform all stack updates in the prologue and leave the stack pointer unchanged until the epilogue.

Функции, выделяющие 4 КБ или больше в стеке, должны проверять, что каждая страница перед последней обрабатывается по порядку.Functions that allocate 4 KB or more on the stack must ensure that each page prior to the final page is touched in order. Это обеспечивает, что никакой код не обойдет страницы защиты, используемые Windows для расширения стека.This ensures that no code can "leap over" the guard pages that Windows uses to expand the stack. Обычно это осуществляется с помощью вспомогательной функции __chkstk, которая получает все выделение стека в байтах, поделенное на 4, из r4 и возвращает итоговое значение выделение стека в байтах обратно в r4.Typically, this is done by the __chkstk helper, which is passed the total stack allocation in bytes divided by 4 in r4, and which returns the final stack allocation amount in bytes back in r4.

Красная зонаRed zone

8-байтовая область сразу после текущего указателя стека зарезервирована для анализа и динамического исправления.The 8-byte area immediately below the current stack pointer is reserved for analysis and dynamic patching. Это позволяет вставить тщательно выверенный код, который хранит 2 регистра в [sp, #-8] и временно использует их для произвольных целей.This permits carefully generated code to be inserted, which stores 2 registers at [sp, #-8] and temporarily uses them for arbitrary purposes. Ядро Windows гарантирует, что эти 8 байт не будут перезаписаны при возникновении исключения или прерывания как в пользовательском режиме, так и в режиме ядра.The Windows kernel guarantees that those 8 bytes will not be overwritten if an exception or interrupt occurs in both user mode and kernel mode.

Стек ядраKernel stack

Стек режима ядра по умолчанию в Windows состоит из трех страниц (12 КБ).The default kernel-mode stack in Windows is three pages (12 KB). Следите за тем, чтобы у создаваемых функций не было большого буфера стека в режиме ядра.Be careful not to create functions that have large stack buffers in kernel mode. Прерывание может возникнуть в тот момент, когда запас стека недостаточен, что вызовет критическую ошибку в виде сбоя стека.An interrupt could come in with very little stack headroom and cause a stack panic bugcheck.

Особенности C/C++C/C++ specifics

Перечисления являются 32-разрядными целочисленными типами, если только хотя бы одно из значений в перечислении не требует хранения в 64-разрядном формате удвоенного слова.Enumerations are 32-bit integer types unless at least one value in the enumeration requires 64-bit double-word storage. В этом случае перечисление повышается до 64-разрядного целочисленного типа.In that case, the enumeration is promoted to a 64-bit integer type.

wchar_t определяется как эквивалент unsigned short для сохранения совместимости с другими платформами.wchar_t is defined to be equivalent to unsigned short, to preserve compatibility with other platforms.

Проверка стекаStack walking

Код Windows компилируется с включенными указателями фреймов (/Oy (подавление указателей фрейма)) для обеспечения быстрой проверки стека.Windows code is compiled with frame pointers enabled (/Oy (Frame-Pointer Omission)) to enable fast stack walking. Обычно регистр r11 указывает на следующее звено в цепочке, которое представляет собой пару {r11, lr}, задающую указатель на предыдущий фрейм в стеке и адрес возврата.Generally, the r11 register points to the next link in the chain, which is an {r11, lr} pair that specifies the pointer to the previous frame on the stack and the return address. Мы рекомендуем также включить указатели фреймов в вашем коде для улучшения профилирования и трассировки.We recommend that your code also enable frame pointers for improved profiling and tracing.

Очистка исключенияException unwinding

Очистка стека во время обработки исключений реализуется посредством кодов очистки.Stack unwinding during exception handling is enabled by the use of unwind codes. Коды очистки представляют собой последовательность байт, хранимых в разделе .XDATA исполняемого образа.The unwind codes are a sequence of bytes stored in the .xdata section of the executable image. Они отвлеченно описывают работу кода пролога и эпилога функции, чтобы можно было нейтрализовать воздействие пролога функции во время подготовки к очистке кадра стека вызывающего объекта.They describe the operation of the function prologue and epilogue code in an abstract manner, so that the effects of a function's prologue can be undone in preparation for unwinding to the caller's stack frame.

ARM EABI задает модель очистки исключения, использующую коды очистки.The ARM EABI specifies an exception unwinding model that uses unwind codes. Однако такой спецификации недостаточно для очистки в Windows, так как требуется обрабатывать случаи, когда процессор находится в середине пролога или эпилога функции.However, this specification is not sufficient for unwinding in Windows, which must handle cases where the processor is in the middle of the prologue or epilogue of a function. Дополнительные сведения о данных и очистке исключений в Windows на ARM см. в статье Обработка исключений ARM.For more information about Windows on ARM exception data and unwinding, see ARM Exception Handling.

Мы рекомендуем использовать для описания динамически созданного кода таблицы динамических функций, заданные в вызовах RtlAddFunctionTable и связанных функций, чтобы созданный код мог принять участие в обработке исключений.We recommend that dynamically generated code be described by using dynamic function tables specified in calls to RtlAddFunctionTable and associated functions, so that the generated code can participate in exception handling.

Счетчик цикловCycle counter

Процессоры ARM под управлением Windows должны поддерживать счетчик циклов, однако прямое использование такого счетчика может вызвать проблемы.ARM processors running Windows are required to support a cycle counter, but using the counter directly may cause problems. Чтобы избежать их, Windows на ARM использует неопределенный код операции для запроса нормализованного 64-разрядного значения счетчика циклов.To avoid these issues, Windows on ARM uses an undefined opcode to request a normalized 64-bit cycle-counter value. В C или C++ используйте встроенную функцию __rdpmccntr64 для вывода соответствующего кода операции; в сборке используйте инструкцию __rdpmccntr64.From C or C++, use the __rdpmccntr64 intrinsic to emit the appropriate opcode; from assembly, use the __rdpmccntr64 instruction. Считывание счетчика циклов на процессоре Cortex-A9 занимает около 60 циклов.Reading the cycle counter takes approximately 60 cycles on a Cortex-A9.

Это действительно счетчик, а не тактовый генератор, поэтому частота подсчета меняется вместе с частотой процессора.The counter is a true cycle counter, not a clock; therefore, the counting frequency varies with the processor frequency. Если вы хотите замерить истекшее время, используйте QueryPerformanceCounter.If you want to measure elapsed clock time, use QueryPerformanceCounter.

См. такжеSee also

Общие вопросы использования Visual C++ ARMCommon Visual C++ ARM Migration Issues
Обработка исключений ARMARM Exception Handling