Koşulsuz Jump Komutları

07:20

Jump komutları sembolik makine dillerinin mutlaka bilinmesi gereken komutlarındandır. Bazı işlemci ailelerinde bu komutlara branch (dallanma) komutları denilmektedir. Jump komutları olmadan yüksek seviyeli dillerdeki if, switch, while for gibi deyimler gerçekleştirilemez. Jump komutları koşulsuz (unconditional) ve koşullu (conditional) olmak üzere ikiye ayrılmaktadır. Koşulsuz jump komutları C’deki goto deyimi gibidir. Koşulsuz olarak EIP yazmacını belli bir değere çeker. Koşulsuz jump komutlarının doğrudan (direct) ve dolaylı (indirect) biçimleri de vardır. Koşulsuz jump komutları pek çok işlemcide olduğu gibi göreli uzaklık değerini operand olarak alır. Doğrudan koşulsuz jump komutlarının son byte’larından sonraki ilk byte göreli uzaklık için sıfır orijini belirtir. Negatif uzaklık "yukarıya", pozitif uzaklık "aşağıya" jump yapılacağı anlamına gelmektedir.

Koşulsuz doğrudan jump komutları operand olarak "göreli uzaklık" miktarını almaktadır. Göreli uzaklıkların sembolik makine dili programcısı tarafından hesaplanması çok zordur. Assembly derleyicileri etiket (label) yöntemi ile bu yükü bizim üzerimizden almaktadır. Sembolik makine dillerinde JMP komutlarının yanına bir etiket ismi verilmektedir. Sembolik makine dili derleyicileri de jmp komutunun sonundan o etiketin bulunduğu uzaklığı hesaplayarak makine komutu oluşturur.

Pekiyi jump komutları operand olarak neden mutlak adres yerine göreli uzunluk almaktadır? Çünkü bu sayede biz kodu bellekte başka yere yüklesek bile o jump komutları yine aynı yere atlamayı sağlayacaktır. Koşulsuz jump komutlarının 8 bit, 16 bit ve 32 bit göreli uzunluk alan biçimleri de vardır. Tabii programcı özel bir belirleme yapmakdıktan sonra derleyici zıplama miktarını hesaplayarak en uygun jump komutunu üretir. Intel sisteminde 8 bit göreli uzunluk alarak yapılan jump işlemlerine "short jump", 16 bit ve 32 bit göreli uzunluk alarak yapılan jump işlemlerine de "near jump" denilmektedir. Pek çok sembolik makine dili derleyicisinde short ya da near anahtar sözcüğü ile bunu isterse programcı belirleyebilmektedir. Örneğin:

. . .
jmp near NEXT ; ...
NEXT:
    call _ExitProcess@4
. . .

Eğer "short" ya da "near" anahtar sözcüklerinin hiçbiri kullanılmamışsa default durumda derleyici en uygun jump komutunu hesaplamaktadır. 32 bit sistemde 16 bit göreli uzunluk için komutta 0x66 ön eki gerekmektedir. Intel’deki koşulsuz jump komutlarının yazmaç ve bellek operandı alan biçimleri de vardır. Yazmaç operandı alan biçimi mutlak jump işlemi yapar. Yani yazmacın içerisindeki değer göreli uzunluk değil, bizzat jump edilecek yerin adrestir. Örneğin:
mov EAX, 0x123469
jmp EAX
Burada koşulsuz olarak 0x123469 adresine jump yapılmaktadır. Koşulsuz jump komutlarının bellek operandı alan biçimleri de vardır. Bu durumda önce o bellek bölgesindeki 32 bit değer çekilir. Oraya mutlak jump uygulanır. Örneğin:
jmp [EAX]
Burada EAX yazmacının içerisinde bulunan adresten 32 bit adres bilgisi çekilerek o adrese dallanma yapılmaktadır. Intel mimarisinde jmp komutlarının operandları yazmaç ya da bellek ise böyle jump’lara “indirect jump” denilmektedir. Örneğin:

[BITS 32]
SECTION .data
   ptrJmp dd EXIT
SECTION .text
global _start
extern _ExitProcess@4
_start:
jmp [ptrJmp]
EXIT:
xor eax, eax
push eax
   call _ExitProcess@4
Burada EXIT etiketinin adresi ptrJmp adresindeki bellek bölgesine yazılmıştır:

SECTION .data
jmpPoint dd EXIT
Sonra oraya aşağıdaki kod parçasında görüleceği üzere dolaylı jump işlemi indirect jump yapılmıştır:
jmp [jmpPoint]

 Bir sonraki yazımız dallanma konusunda daha önemli bir parçayı oluşturan koşullu dallanma konusunda olacaktır.