Updating variable that lives in the data segment f

2019-08-29 06:46发布

问题:

I currently have three segments of memory, my main data segment, stack segment and the segment where my API lives. The following instructions are executed from the data segment, they push the address of cursorRow and welcomeMsg then do a far call to the function in my API segment. The cursorRow variable lives in the main data segment that is calling the API function. The call looks like this:

  push cursorRow
  push welcomeMsg
  call API_SEGMENT:API_printString

How can I alter cursorRow, inside of the segment where my API lives, through the stack? cursorRow needs to be updated from the API. NO API functions alter the data segment. I have tried things like: inc byte [ds:bp+8] and add [ds:bp+8], 1. Here is the API procedure being called:

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 

it prints strings, but the cursorRow variable doesn't correctly update. I hope I'm clear enough on my issue. It's hard to explain :D

回答1:

This is because you passed the pointer to cursorRow, not cursorRow itself. When you perform

inc [ds:bp+8]

you: 1) get the value of bp, 2) add 8, 3) assume the result is a pointer in ds, 4) increment the value stored there (the pointer to cursorRow). Since the pointer is stored on the stack, you are incrementing the pointer when you do this. What you need to do is take the pointer off of the stack and increment the value that points to.

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

This code: 1) gets the value of bp, 2) adds 8, 3) assumes the result is a pointer in ss, 4) load the value stored there (the pointer to cursorRow) into bx, 5) assumes bx is a pointer in ds, 6) increments the value stored there (the value of cursorRow).



回答2:

It's look like you just pushed the value of cursorRow onto the stack. Without the address you cannot update it. With the address you can easily reference that addresses' value, put it into a register, perform operations on it, then take the value that's in that register and put it into the address of cursorRow.