Jumping to labels with same name as variable

Programming, for all ages and all languages.
Post Reply
phillid
Member
Member
Posts: 58
Joined: Mon Jan 31, 2011 6:07 pm

Jumping to labels with same name as variable

Post by phillid »

Hey. I was just wondering whether it's possible to do the following:

Code: Select all

     ; Assembler Code (duh)
     mov [myvar], othervar
     jmp [myvar]                    ; jump to the label specified in [myvar]?
     mylabel:  jmp mylabel          ; Hang

     myvar     times (256) db '0'   ; define variable 'myvar'
     othervar  db  "mylabel"        ; define variable 'othervar' with value 'mylabel'
So I want to have a variable that holds a label to jump to, and be able to jump to that variable by putting it in the JMP instruction.
I have a question:
- Will the computer jump to the address that [myvar] is held at, instead of the label that [myvar] contains?


Thanks for any help!
phillid - Newbie-ish operating system developer with a toy OS on the main burner
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Jumping to labels with same name as variable

Post by Brendan »

Hi,
phillid wrote:So I want to have a variable that holds a label to jump to, and be able to jump to that variable by putting it in the JMP instruction.
Assembly language doesn't have variables, and labels are just a way to give addresses names. Everything is either an address or data at an address.

Even though "jumping to data at an address" doesn't make much sense in practice, it is entirely possible. For example:

Code: Select all

        jmp foo           ;JMP to the data at an address

foo:    dd 0              ;Some data at an address
It's also possible to jump to the address stored at another address. This is called an indirect jump:

Code: Select all

        jmp [foo]           ;JMP to the address stored at an address

foo:    dd bar              ;Some data at an address

bar:    ret

Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Fanael
Member
Member
Posts: 38
Joined: Fri Oct 16, 2009 9:20 am

Re: Jumping to labels with same name as variable

Post by Fanael »

Brendan wrote:Even though "jumping to data at an address" doesn't make much sense in practice, it is entirely possible.
It makes very much sense and most if not all programs do this very very often, actually. Code is data, too. What are subroutine calls, conditional branches, agus araile, if not "jumping to data at an address"?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Jumping to labels with same name as variable

Post by Combuster »

There is a difference between jumping to an address (direct), and jumping to an address described by data at another address (indirect).

Anyway, all conditionals are jumps to addresses, and most function calls are. Virtual functions and function pointers are jumps to location stored at address, and switch statements are often optimized to jumps to location stored at nth entry in list (another indirect data at address)

That said, you can split any indirect jump into a load and a direct jump.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
phillid
Member
Member
Posts: 58
Joined: Mon Jan 31, 2011 6:07 pm

Re: Jumping to labels with same name as variable

Post by phillid »

Well, I have found a function called 'cmpstr' which is meant to compare two strings but I don't have a way to tell it which label to jump to if the strings are equal, or not. I thought I could have a 'variable' that I could set.

Does anyone have any suggestions?

Here's the cmpstr code ('put' puts text on the screen):

Code: Select all

string1	db	'this is string 1',0
string2	db	'this is string 2',0
cmpstr:	
	lea si, string1		; ds:si points to first string
	lea di, string2		; ds:di points to second string
	dec di
	inc di				; ds:di -> next character in string2
	lodsb				; load al with next char from string 1
	cmp [di], al		; compare characters
	jne NotEqual		; jump out of loop if they are not the same
	cmp al, 0			; they are the same, but end of string?
	jne cmpstr			; no - so go round loop again
	; ------------------------------------
	;  Strings are equal
	; ------------------------------------
	mov	si, equalmsg
	call	put
	retn				; continue with rest of program
	; ------------------------------------
	;  Strings are not equal
	; ------------------------------------
	NotEqual:
	mov	si, notequalmsg
	call	put
cmpstrd:
	retn
phillid - Newbie-ish operating system developer with a toy OS on the main burner
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Jumping to labels with same name as variable

Post by Solar »

It's a bad sign when I can answer someone's ASM question...
phillid wrote:Well, I have found a function called 'cmpstr' which is meant to compare two strings but I don't have a way to tell it which label to jump to if the strings are equal, or not.

Code: Select all

; ...
	mov	si, equalmsg
; ...
	mov	si, notequalmsg
; ...
        retn
These here are the two "outcomes" of the function, which obviously has been designed to point si at some message depending on outcome. You want to "jump to label" instead. Obviously you have to modify the function.

Put two addresses (labels) into specific registers, and have the function return one of them depending on whether the strings are equal or not. After calling the function, jump to the "return" address.

Code: Select all

    mov bx, label_if_equal
    mov cx, label_if_not_equal
    call cmpstr
    jmp [ax]

cmpstr:
    ; ...
    mov ax, bx   ; instead of mov si, equalmsg
    ; ...
    mov ax, cx   ; instead of mov si, notequalmsg
    ; ...
    retn
Which, of course and now that I think of it, is just a more complicated version of:

Code: Select all

    mov bx, label_if_equal
    mov cx, label_if_not_equal
    jmp cmpstr

cmpstr:
    ; ...
    jmp bx   ; instead of mov si, equalmsg
    ; ...
    jmp cx   ; instead of mov si, notequalmsg
Does that help you?
Every good solution is obvious once you've found it.
phillid
Member
Member
Posts: 58
Joined: Mon Jan 31, 2011 6:07 pm

Re: Jumping to labels with same name as variable

Post by phillid »

Yeah, thanks, but that's what I was saying in my example in the first place!
Don't get me wrong, I'm not mad at you, I'm just a bit annoyed at others for not giving me a simple, short answer.
They mislead me!

Oh well!

Thanks anyway!
phillid - Newbie-ish operating system developer with a toy OS on the main burner
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Jumping to labels with same name as variable

Post by Solar »

All I did was replying to your last post:
I don't have a way to tell it which label to jump to if the strings are equal, or not.
And I can say from experience, there is no misleading, only misunderstanding.
Every good solution is obvious once you've found it.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Jumping to labels with same name as variable

Post by Combuster »

I think he's either trying to implement a symbol table of sorts, or the concept of return values has gone amiss:

Code: Select all

        CALL compare ; in this example, ZF (zero/equal) gets set to the result 
                     ; like a rep cmpsb would do
        JE .equal
.notequal:
        (...)
.equal:
        (...)
Otherwise, you'll want a construction somewhat like the following:

Code: Select all

typedef struct entry
{
    const char * name;
    int (*target)(void);    // function pointer
} entry;

static entry * table = {
  {"name1", &function1},
  {"name2", &function2},
  {NULL, NULL}
};

int lookup_and_call(const char * functionname)
{
    entry * current = table;
    while(current)
    {
        if (strcmp(functionname, current->name) == 0) return current->target();
        current++;
    }
}
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply