Page 1 of 1

Jumping to labels with same name as variable

Posted: Sun Feb 27, 2011 1:26 am
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!

Re: Jumping to labels with same name as variable

Posted: Sun Feb 27, 2011 2:05 am
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

Re: Jumping to labels with same name as variable

Posted: Sun Feb 27, 2011 1:03 pm
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"?

Re: Jumping to labels with same name as variable

Posted: Sun Feb 27, 2011 1:49 pm
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.

Re: Jumping to labels with same name as variable

Posted: Mon Feb 28, 2011 12:16 am
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

Re: Jumping to labels with same name as variable

Posted: Mon Feb 28, 2011 2:09 am
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?

Re: Jumping to labels with same name as variable

Posted: Mon Feb 28, 2011 11:16 pm
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!

Re: Jumping to labels with same name as variable

Posted: Tue Mar 01, 2011 12:39 am
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.

Re: Jumping to labels with same name as variable

Posted: Tue Mar 01, 2011 1:50 am
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++;
    }
}