2017-01-19 2 views
1

Я немного новичок в языке ассемблера и хочу понять, как он работает на более старой системе. Я понимаю, что большая модель памяти использует большие указатели, в то время как малая модель памяти использует около указателей, а обратный адрес в большой модели - 4 байта вместо двух, поэтому первый параметр изменяется от [bp+4] до [bp+6]. Однако в процессе адаптации графической библиотеки от небольшой до большой модели есть и другие тонкие вещи, которые я, кажется, не понимаю. Выполнение этого кода с большой моделью памяти от C предполагается очистить экран, но вместо этого он вешает систему (она была собрана с TASM):Как перевести сборку DOS, предназначенную для небольшой модели памяти, в большую модель памяти?

; void gr256cls(int color , int page); 

COLOR equ [bp+6] 
GPAGE equ [bp+8] 

    .MODEL LARGE,C 
.186 
    public C gr256cls 
    .code 
gr256cls PROC 
    push bp 
    mov bp,sp 
    push di 
    pushf 
    jmp skip_1 
.386 
    mov ax,0A800h 
    mov es,ax 
    mov ax,0E000h 
    mov fs,ax 
    CLD 
    mov al,es:[bp+6] 
    mov ah,al 
    mov bx,ax 
    shl eax,16 
    mov ax,bx 

    cmp word ptr GPAGE,0 
    je short cls0 
    cmp word ptr GPAGE,2 
    je short cls0 
    jmp short skip_0 
cls0: 
    mov bh,0 
    mov bl,1 
    call grph_cls256 
skip_0: 
    cmp word ptr GPAGE,1 
    je short cls1 
    cmp word ptr GPAGE,2 
    je short cls1 
    jmp short skip_1 
cls1: 
    mov bh,8 
    mov bl,9 
    call grph_cls256 
skip_1: 
.186 
    popf 
    pop di 
    pop bp 
    ret 
.386 
grph_cls256: 
    mov fs:[0004h],bh 
    mov fs:[0006h],bl 
    mov cx,16384 
    mov di,0 
    rep stosd 
    add word ptr fs:[0004h],2 
    add word ptr fs:[0006h],2 
    mov cx,16384 
    mov di,0 
    rep stosd 
    add word ptr fs:[0004h],2 
    add word ptr fs:[0006h],2 
    mov cx,16384 
    mov di,0 
    rep stosd 
    add word ptr fs:[0004h],2 
    add word ptr fs:[0006h],2 
    mov cx,14848 ;=8192+6656 
    mov di,0 
    rep stosd 
    ;; Freezes here. 
    ret 
gr256cls ENDP 
    end 

Он висит на ret в конце grph_256cls. На самом деле, даже если я сразу же ret с самого начала функции, он все еще висит сразу после. Есть ли полный список различий при сборке кодирования в двух режимах, поэтому я могу более легко понять, что происходит?

EDIT: Чтобы уточнить, это оригинальный источник. Это не сгенерированный вывод; он предназначен для сборки и подключения в библиотеку.

+0

Обратите внимание, что в большой модели кода вызовы функций вызывают четырехбайтовый обратный адрес в стеке. Возможно, вы захотите рассмотреть это в определении 'COLOR' и' GPAGE'. – fuz

+0

Первоначально параметры были «[bp + 4]» и «[bp + 6]», с адресом возврата в два байта, помещенным в стек, поэтому я добавил еще два байта для каждого. – nonbirithm

+0

Вам нужно показать полный код со всеми шагами, которые вы предпринимаете для его создания и запуска, чтобы мы могли воспроизвести проблему. При необходимости уменьшите код C, который вызывает эту функцию, до минимума, необходимого для воспроизведения проблемы. Сделайте так, чтобы код в вашем сообщении был точно таким же, как ваш. –

ответ

1

Я изменил grph_256cls к процедуре с PROC FAR и теперь он работает без проблем:

grph_cls256 PROC FAR 
    ... 
grph_cls256 ENDP 

вопрос должен был сделать с тем, как C ожидает функции будет называться в зависимости от модели памяти. В большой модели памяти все вызовы функций: far. Я не помещал это предположение в подпрограмму grph_256cls при попытке выполнить call, поэтому вместо этого был скопирован код, который не нажимал/не вводил правильные значения в стеке.

+0

Это не имеет никакого отношения к тому, что ожидает C, потому что это не код C, который вызывает 'grph_256cls'. –

+1

@RossRidge: А, но это так. TASM автоматически настраивается для того, что ожидает C. – Joshua

+0

@ Joshua Нет, это не так. В этом проблема, если бы это было так последовательно. –

Смежные вопросы