Сбой процедуры встроенной сборки при доступе к аргументам - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть следующая процедура x86, которую я пытаюсь вызвать из программы c:

        PUBLIC _funcf  
_TEXT SEGMENT WORD PUBLIC 'CODE'
_funcf  PROC
    push    EBP
    mov     EBP,    ESP
    sub     ESP,    4                   ; make space for x (4)

    mov     EAX,    DWORD PTR 4[ebp]    ; move v1 into EAX

    ...

    pop     EBP
    ret
_funcf  ENDP

_TEXT   ENDS  
        END  

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

extern "C" int funcf( int32_t v1, int32_t v2, int32_t v3 );

int main( int argc, char *vargs[] )
{

    ...

    output = funcf( v1, v2, v3 );

    ...

}

Однако при запуске получено нарушение прав доступа по команде mov EAX. Я посмотрел на представление памяти с помощью отладчика, и память, хранящаяся в ebp+4, является ожидаемым аргументом, поэтому я был озадачен тем, что вызывало сбой. Я заметил, что адрес памяти, указанный нарушением прав доступа, не совпадает с ebp+4, и, просмотрев разборку моего кода сборки, я обнаружил, что он переводится в

mov         ax,word ptr [di+4]  

где di указывает на совершенно другой адрес, и это адрес, указанный в исключении. Является ли это просто вводящим в заблуждение продуктом работы разборки, или мой код фактически заменен на эту неожиданную операцию? Несмотря на это, источник катастрофы мне неизвестен.

1 Ответ

0 голосов
/ 02 ноября 2018

Как оказалось, SEGMENT по умолчанию было USE16 вместо USE32 / FLAT, что приводило к его сборке в 16-битном режиме, несмотря на небольшое объяснение в документации .

Также, как сказал Майкл, файл сборки можно упростить до:

.model flat, C

.code

funcf   PROC
    push    EBP
    mov     EBP,    ESP
    sub     ESP,    4                   ; make space for x (4)

    mov     EAX,    DWORD PTR 8[ebp]    ; move v1 into EAX

    ...

    mov     ESP,    EBP
    pop     EBP
    ret
funcf   ENDP

END

для упрощения интеграции с кодом c.

...