Обновление переменной, которая находится в сегменте данных из стека и его сегмента

В настоящее время у меня есть три сегмента памяти: основной сегмент данных, сегмент стека и сегмент, в котором живет мой API. Следующие инструкции выполняются из сегмента данных, они передают адрес cursorRow и welcomeMsg, а затем выполняют дальний вызов функции в моем сегменте API. Переменная cursorRow находится в основном сегменте данных, который вызывает функцию API. Вызов выглядит так:

  push cursorRow
  push welcomeMsg
  call API_SEGMENT:API_printString

Как я могу изменить cursorRow внутри сегмента, в котором живет мой API, через стек? cursorRow необходимо обновить из API. НИКАКИЕ функции API не изменяют сегмент данных. Я пробовал такие вещи, как: inc byte [ds:bp+8] и add [ds:bp+8], 1. Вот вызываемая процедура API:

printStringProc:
    push bp 
    mov bp, sp
    mov si, [bp+6]
    .printloop:
        lodsb
        cmp al, 0
        je printStringDone
        mov ah, 0x0E ; teletype output
        mov bh, 0x00 ; page number
        mov bl, 0x07 ; color (only in graphic mode)
        int 0x10
        jmp .printloop
    printStringDone:
    ; move the cursor down
    mov ah, 02h ; move cursor
    mov dh, [bp+8]
    mov dl, 0 ; column
    mov bh, 0 ; page number
    int 10h

    add [ds:bp+8], 1

  pop bp
  retf 

он печатает строки, но переменная cursorRow не обновляется правильно. Надеюсь, я достаточно ясно выразился по своему вопросу. Это сложно объяснить :D


person TheFuzz    schedule 12.07.2011    source источник


Ответы (2)


Это потому, что вы передали указатель на cursorRow, а не на сам cursorRow. Когда вы выполняете

inc [ds:bp+8]

вы: 1) получаете значение bp, 2) добавляете 8, 3) предполагаете, что результатом является указатель в ds, 4) увеличиваете значение, хранящееся там (указатель на cursorRow). Поскольку указатель хранится в стеке, при этом вы увеличиваете указатель. Что вам нужно сделать, так это убрать указатель со стека и увеличить значение, которое указывает.

mov bx, [bp+8]
inc [bx]

Этот код: 1) получает значение bp, 2) добавляет 8, 3) предполагает, что результатом является указатель в ss, 4) загружает хранящееся там значение (указатель на cursorRow) в bx, 5) предполагает, что bx является указателем в ds, 6) увеличивает хранящееся там значение (значение cursorRow).

person ughoavgfhw    schedule 12.07.2011
comment
Можете ли вы запустить его в отладчике, чтобы убедиться, что загружается правильный адрес? Если вы работаете на виртуальной машине, bochs можно скомпилировать с помощью хорошего встроенного отладчика. Кроме того, курсор двигается правильно? Похоже, что вы также используете указатель на cursorRow как dh для этого прерывания. - person ughoavgfhw; 13.07.2011

Похоже, вы только что поместили значение cursorRow в стек. Без адреса вы не сможете его обновить. С адресом вы можете легко сослаться на значение этого адреса, поместить его в регистр, выполнить над ним операции, затем взять значение из этого регистра и поместить его в адрес cursorRow.

person Community    schedule 13.02.2012