NASM - The Netwide Assembler

NASM Forum => Programming with NASM => Topic started by: tysonprogrammer on July 24, 2022, 08:29:45 PM

Title: Accessing pushed value from a label
Post by: tysonprogrammer on July 24, 2022, 08:29:45 PM
I am writing a program in x86 assembly for FreeDOS. I am trying to stick with 16 bit registers so it will work on older hardware.
The program will create a framed box on the screen and I am pushing a structure with the values for the box on the stack to a routine. I would like to know if I can store this stack value in a label. I am currently using si and that works fine but if I can not use si then I have use for other things. I know I can push it onto the stack to save it but if I don't have to the would be great.

I have the following structure defined.

Code: [Select]
struc BOX_FRAME
    .TopX:      resb    1
    .TopY:      resb    1
    .BottomX:   resb    1
    .BottomY:   resb    1
    .Color:     resb    1
endstruc

and this label defined in my data section

Code: [Select]
section data
    window:
        istruc BOX_FRAME
            at BOX_FRAME.TopX,          db      0
            at BOX_FRAME.TopY,          db      0
            at BOX_FRAME.BottomX,       db      0
            at BOX_FRAME.BottomY,       db      0
            at BOX_FRAME.Color,         db      0
        iend

I am passing this on the stack using this
Code: [Select]
   mov ax, data
    mov ds, ax

    mov [window+BOX_FRAME.TopX],    byte 4
    mov [window+BOX_FRAME.TopY],    byte 4
    mov [window+BOX_FRAME.BottomX], byte 25
    mov [window+BOX_FRAME.BottomY], byte 10
    mov [window+BOX_FRAME.Color],   byte COLOR_YELLOW
    or [window+BOX_FRAME.Color],    byte COLOR_BLUE
    push window
    call drawWindow

in drawWindow I have this

Code: [Select]
drawWindow:
.init:
    push bp
    mov bp, sp
   
    mov si, word [bp+4]

I have the following single-line macros defined

Code: [Select]
%define x1  byte [si+BOX_FRAME.TopX]
%define y1  byte [si+BOX_FRAME.TopY]
%define x2  byte [si+BOX_FRAME.BottomX]
%define y2  byte [si+BOX_FRAME.BottomY]
%define color byte [si+BOX_FRAME.Color]

Here is an example of how the single-line macros are used.

Code: [Select]
mdraw_corner x1, y1, BORDER_TOPLEFT

mdraw_corner is a multi-line macro

Using si works just fine but I am wondering if I can use a label instead. if so, how would I use it to address a value in the structure.

For example If I have a label defined

Code: [Select]
section bss
    .draw_struct  resw    1

I am attaching what it currently looks like when it runs, for your enjoyment and aww.


thanks much,
Tyson
Title: Re: Accessing pushed value from a label
Post by: Frank Kotler on July 25, 2022, 03:49:20 AM
 Hi Tyson,

I may very well be confused!

You define a structure. Good.
You define  an instance of the structure named "window". Only one, as far as I can see. This may be where I'm confused.  You pass "window" to subroutines on the stack, but it's always the same instance of the structure... or I'm confused... You fill in different values in different subroutines, but always the same instance... IF I'm right. So there's no need to pass "window" and thus no need tp use si.

You could make a "local" ("automatic") instance of your structure on the stack...
Code: [Select]
mov bp, sp
sub sp, Box_Frame_size
; and make your instance in this space
mov sp, bp ; make it go away
but that's not what I think I see...
so:
Code: [Select]
%define x1  byte [window+BOX_FRAME.TopX]
;etc
without using si should work... I think...
But you may want to use different instances... or perhaps you do and I'm missing it. Depends on how confused I am. :)

Best,
Frank
Title: Re: Accessing pushed value from a label
Post by: tysonprogrammer on July 25, 2022, 10:10:56 PM
Frank,

Thanks for your reply. Yes I could use the window instance since it is essentially global and maybe that's where I got off track coming for a OOP language. But just for giggles is there a way to use a reference label instead of si? Or is si used for that?

thanks,
Tyson
Title: Re: Accessing pushed value from a label
Post by: Frank Kotler on July 26, 2022, 02:56:41 AM
Sure. Use bx or di.
I don't think that's what you're looking for. I'm not sure what you are looking for.
Code: [Select]
foo equ bp + 4
?
Best,
Frank


Title: Re: Accessing pushed value from a label
Post by: fredericopissarra on July 26, 2022, 12:44:32 PM
You mean something like this?
Code: [Select]
  bits  16

struc BOX_FRAME
  .TopX:      resb    1
  .TopY:      resb    1
  .BottomX:   resb    1
  .BottomY:   resb    1
  .Color:     resb    1
              resb    1   ; To make it word sized.
endstruc

struc STK_FRAME
        resw  1   ; return address
  .wnd: resb  BOX_FRAME_size
endstruc

; Yep... using cdecl convention:
;
;   push window
;   call f
;   add  esp,4

f:
  ; Why do you need to use 16 bits alias registers, even in 16 bit code?
  ; 386 registers and instructions are available!
  mov   al,[esp + STK_FRAME.wnd + BOX_FRAME.Color]
  ;...
  ret
Title: Re: Accessing pushed value from a label
Post by: Frank Kotler on July 26, 2022, 06:33:24 PM
Dunno. Does it do what you want?

I think you might be better off to use si and quit fighting it... maybe...

Best,
Frank

Title: Re: Accessing pushed value from a label
Post by: fredericopissarra on July 27, 2022, 01:45:56 PM
My point: Instead trying to remember if you should add or subtract N from the stack pointer to access an argument pushed on stack, use structures... And more: Using BP to access the stack was wildely used on 8086 and 80286 because there were no other way to do it... Since 386 you can use ESP to access the stack directly.

The prologue/epilogue:

Code: [Select]
  push bp
  mov  bp,sp    ; prologue
  ...
  pop   bp        ; epilogue

  ret
Aren't necessary anymore, if you use ESP to access the stack.

Yep... ESP is 32 bits long, but in 16 bits mode the upper 16 bits os E?? will be discarded in an effective address calculation.

Of course, using ESP will add a prefix (0x67 maybe) and even a longer opcode, but this is faster then saving/retrieving BP to/from the stack.

The same argument can be made for using 32 bits registers as base/index on an effective address calculation, instead of the fixed [BX+(SI/DI)+offset]... Since we are free to use any registers (including repeating them) as base and index, the code tends to be shorter. And remember that 386+ has a scaling of indexes as well (not available on 80(2)86).

Simple example: Multiplying a register by 10:
Code: [Select]
; Multiply EAX by 10;
  lea eax,[eax+eax*4]  ; multiply by 5
  shl eax,1 ; multiply by 2
This LEA isn't possible on pre-386 80x86 family processors. To do the same with AX on 8086 code:
Code: [Select]
  mov cl,2
  mov bx,ax
  shl ax,cl          ; There is no SHL AX,imm8 instruction on 80(2)86
  add ax,bx
  shl ax,1           ; except this one!

In general, using 32 bits registers on 16 bits code leads to better code.

[]s
Fred
Title: Re: Accessing pushed value from a label
Post by: Frank Kotler on July 27, 2022, 04:42:57 PM
Hi Fred,

Golly, I'm losing it! I didn't realize that it was you I was addressing last time.

I agree that 386 registers are way more convenient. Tyson says he wants to stick with 16-bit registers so it'll run on older hardware. In a museum? In the basement? Whatever.

But that's a slightly different question than accessing the stack through a label/ >aybr ovrtlaying the stack with a structure name as you show is what Tyson's looking for.

Best,
Frank

Title: Re: Accessing pushed value from a label
Post by: fredericopissarra on July 27, 2022, 06:58:58 PM
Hi Fred,

Golly, I'm losing it! I didn't realize that it was you I was addressing last time.

I agree that 386 registers are way more convenient. Tyson says he wants to stick with 16-bit registers so it'll run on older hardware. In a museum? In the basement? Whatever.

Hehehehehehehe... Maybe Tyson have a time machine and want to go back to the 1980's... I've seen "stranger things"... :)
Quote
But that's a slightly different question than accessing the stack through a label/ >aybr ovrtlaying the stack with a structure name as you show is what Tyson's looking for.
Maybe that helps...

[]s, Frank!
Fred
Title: Re: Accessing pushed value from a label
Post by: Frank Kotler on July 27, 2022, 08:34:54 PM

Hehehehehehehe... Maybe Tyson have a time machine and want to go back to the 1980's... I've seen "stranger things"... :)

Maybe I can hitch a ride with  him. I was a young fellow in the 1980's. Not like now with my
memory all shot. :(

Best,
Frank


.
Title: Re: Accessing pushed value from a label
Post by: tysonprogrammer on July 27, 2022, 11:20:10 PM
Thanks Fred and Frank

I will stick with si, it's just a pet project and I have no problem with 32-bit registers. Wish I had a time machine so I could go back and learn assembly at a much younger age :)

Yyson