Языковой стек и подпрограмма на ассемблере - PullRequest
0 голосов
/ 13 декабря 2011

Я действительно не понимаю, как работают указатели стека и указатели байтов. Вот фрагмент кода, на который ссылается проблема:

    .data
v1  db  'AB'
v2  db  'CD'
v3  db  'EF

    .code
start:
     mov  ax,@data
     mov  ds,ax
     mov  sp,0100h

;call the subroutine
     mov  ax,offset v1
     push ax
     mov  ax,offset v2
     push ax
     call subr
retsub:

Подпрограмма:

subr:
     push bp
     mov  bp,sp
     mov  si,[bp+6]
     add  si,1
     mov  dl,[si]
     mov  ah,2
     int  21h
     pop  bp
     ret

На три контрольных вопроса, связанных с этой проблемой, есть ответы:
1. После mov bp,sp в подпрограмме значение шестнадцатеричного значения в bp равно 00F8.
2. Подпрограмма записывает один символ ASCII в стандартный вывод. Пишет B.
3. Шестнадцатеричное значение в регистре sp после возврата подпрограммы в основную программу по инструкции на метке retsub равно 00FC.

Может кто-нибудь провести меня через шаги, чтобы я мог немного лучше понять этот процесс?

Таблица данных смещения, которую я имею:

offset  00  01  02  03  04  05
data    41  42  43  44  45  46

В моей голове я подхожу к этой проблеме:

mov  sp,0100h      ;sp = 0100
mov  ax,offset v1  ;ax = 4142
push ax            ;4142 is pushed onto the stack
mov  ax,offset v2  ;ax = 4344
push ax            ;4344 is pushed onto the stack
call subr

stack
------
|4344|
------
|4142|
------

Это насколько я понимаю, и я уверен, что я даже не делаю эту часть правильно. Если вы можете, пожалуйста, разберитесь с тем, что такое bp и sp с каждым шагом, чтобы я мог следовать и, надеюсь, применить это к другой проблеме обзора.

Ответы [ 2 ]

3 голосов
/ 13 декабря 2011

Каждый толчок уменьшается sp на размер толкаемого элемента. Каждая попса увеличивается sp аналогично.

Итак, вы начинаете с sp = 100h, затем вы

  1. вычесть 2 с push ax
  2. вычесть 2 с push ax
  3. вычтите 2 с помощью call subr, потому что call отправляет адрес возврата, и он здесь 16-битный
  4. вычтите 2 с push bp и получите sp = 0F8h
  5. добавить 2 с pop bp
  6. добавьте 2 с помощью ret, удалите 16-битный адрес возврата и получите sp = 0FCh
1 голос
/ 13 декабря 2011

После mov bp, sp в подпрограмме значение шестнадцатеричного значения в bp равно 00F8

Да, поскольку sp инициализируется с помощью 100h, тогда передаются два аргумента размером в слово (push ax), вызывается подпрограмма, которая помещает 2-байтовый адрес возврата в стек, и выполняется последний push bp, который уменьшает sp еще на 2 байта.Таким образом, мы имеем 100h-2-2-2-2 = 00F8h.В ЦП стека увеличивается объем памяти.

Шестнадцатеричное значение в регистре sp после возврата подпрограммы в основную программу по инструкции на метке retsub равно 00FC.

Это потому, что подпрограмма завершается с инструкцией «pop bp», а затем с командой ret, которая извлекает (считывает и увеличивает sp) адрес возврата из стека.Итак, 00F8 + 2 + 2 = 00FC.

...