Use COUNTW().
 
First let's convert your listing into an actual dataset.
data have;
  input ID Var1 :$40. Var1Count :$20.;
cards4;
 1 abc;bde;cf 1;2;5
 2 x;yz       3;1
 3 a;x        2;7
 4 cf;bdx;yz  6;3;2
 5 .          .
 6 x          1
 7 abc        3
 8 xz;adk     2;8
 9 a          3
10 bc;bd      2;1
;;;;
You will need to decide how long to make the NEW var1 variable.  For this example let's set the old one to length $40 and the new on to $20.  Let's make the new count variable numeric instead of character.
 
Now just use a DO loop to output each pair of values.
data want;
  set have;
  length _var1 $20 count 8 ;
  do index=1 to countw(var1,';');
    _var1 = scan(var1,index,';');
    count = input(scan(var1count,index,';'),32.);
    output;
  end;
  keep id _var1 count;
  rename _var1=Var1 count=Var1Count ;
run;
Result

If your original string actually have those extra spaces after the semicolons then you will probably want to add in a LEFT() function call to remove them.
    _var1 = left(scan(var1,index,';'));
You might want to also keep the INDEX variable so you know the original order the values were in inside the character strings.