日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

汇编学习笔记(二):转移指令

發(fā)布時間:2024/7/23 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 汇编学习笔记(二):转移指令 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

章節(jié)目錄

  • 轉(zhuǎn)移指令原理
  • jmp 指令
  • jcxz 指令
  • loop 指令
  • ret 和 retf 指令
  • call 指令
  • call+ret
  • 作者能力有限, 如果您在閱讀過程中發(fā)現(xiàn)任何錯誤, 還請您務必聯(lián)系本人,指出錯誤, 避免后來讀者再學習錯誤的知識.謝謝!

    本文中所有程序均在DOSBox下使用MASM, LINK編譯運行

    轉(zhuǎn)移指令原理

    轉(zhuǎn)移指令是可以控制 CPU 執(zhí)行內(nèi)存中某處代碼的指令. 而 CPU 執(zhí)行內(nèi)存中哪處的指令是由 CS 和 IP 寄存器中的決定的. 因此, 轉(zhuǎn)移指令是通過修改 CS 和 IP 寄存器的值來控制 CPU 對指令的執(zhí)行的.

    只修改 IP 的轉(zhuǎn)移行為稱為 段內(nèi)轉(zhuǎn)移.
    同時修改 CS 和 IP 的轉(zhuǎn)移行為稱為 段間轉(zhuǎn)移.

    由于轉(zhuǎn)移指令對 IP 的修改范圍不同, 段內(nèi)轉(zhuǎn)移又分為: 短轉(zhuǎn)移和近轉(zhuǎn)移.
    短轉(zhuǎn)移: 對 IP 修改范圍為 -128 ~ 127.
    近轉(zhuǎn)移: 對 IP 修改范圍為 -32768 ~ 32767.

    jmp 指令

    jmp為無條件轉(zhuǎn)移指令, 可以修改 IP 或者同時修改 CS 和 IP.

    jmp short 標號

    這條指令完成段內(nèi)短轉(zhuǎn)移. 對 IP 的修改范圍為:-128 ~ 127. 執(zhí)行完該指令之后, CS 的值不變, IP 指向標號在段中的偏移地址.

    示例:

    在上面程序中我們通過 jmp short s 將 IP 指向標號 s 的偏移地址. 當程序執(zhí)行到 jmp 時, 會直接跳轉(zhuǎn)到 s 處, 從 s 處繼續(xù)往下執(zhí)行.

    jmp far ptr 標號

    這條指令完成段間轉(zhuǎn)移, 又稱為遠轉(zhuǎn)移. 執(zhí)行完該指令之后, CS 指向標號所在的段基址, IP 指向標號在段中的偏移地址.

    示例:

    在上面程序中我們通過 jmp far ptr s 將 CS 指向標號 s 的段基址, IP 指向標號 s 的偏移地址. 當程序執(zhí)行到 jmp 時, 會直接跳轉(zhuǎn)到 s 處, 從 s 處繼續(xù)往下執(zhí)行.

    其他 jmp 指令

    當然轉(zhuǎn)移地址可以存儲在寄存器或者內(nèi)存中, 相應的語法如下:

    jmp reg // 其中 reg 為 16位寄存器,其中存儲這要跳轉(zhuǎn)的偏移地址.

    jmp word ptr 內(nèi)存單元地址 // 段內(nèi)轉(zhuǎn)移, 內(nèi)存單元存放目的偏移地址.
    // 示例:
    mov ax, 0123H
    mov ds:[0], ax
    jmp word ptr [ds]:[0] // IP = 0123H

    jmp dword ptr 內(nèi)存單元地址 // 段間轉(zhuǎn)移, 內(nèi)存單元兩個字節(jié),
    //高地址處存放著轉(zhuǎn)移的目的段基址, 低字節(jié)存放的是轉(zhuǎn)移的目的偏移地址.
    // 示例:
    mov ax, 0123H
    mov ds:[0], ax
    mov word ptr ds:[2], 0
    jmp word ptr [ds]:[0] // CS = 0, IP = 0123H

    Note: 轉(zhuǎn)移指令,不僅僅可以向后跳轉(zhuǎn), 亦可以向前跳轉(zhuǎn).

    jcxz 指令

    該指令為有條件轉(zhuǎn)移指令. 所有有條件轉(zhuǎn)移指令都是短轉(zhuǎn)移.

    指令格式: jcxz 標號(如果 CX = 0, 轉(zhuǎn)移到標號處執(zhí)行)

    jcxz 的功能相當于: if (CX == 0) jmp short 標號
    當 CX != 0 時, jcxz 什么也不做, 程序繼續(xù)向下執(zhí)行.

    示例:

    loop 指令

    該指令在上一篇文章中已經(jīng)涉及,示例可參考匯編語言筆記(一)

    ret 和 retf 指令

    ret 指令用棧中的數(shù)據(jù), 修改 IP 的值, 實現(xiàn)近轉(zhuǎn)移.
    retf 指令用棧中的數(shù)據(jù), 修改 CS 和 IP 的值, 實現(xiàn)遠轉(zhuǎn)移.

    CPU 執(zhí)行 ret 指令時, 進行如下兩步操作:

    IP = SS * 16 + SP
    SP = SP + 2

    相當于: pop IP

    CPU 執(zhí)行 retf 執(zhí)行時, 進行如下四步操作:

    IP = SS * 16 + SP
    SP = SP + 2
    CS = SS * 16 + SP
    SP = SP + 2

    相當于:
    pop IP
    pop CS

    示例:

    ret 用法

    retf 用法:

    上述程序中, ret/retf 執(zhí)行執(zhí)行后, IP = 0, CS:IP 指向代碼段的第一條指令.

    call 指令

    CPU 執(zhí)行 call 指令時, 執(zhí)行以下兩步操作:

    將當前的 IP 或者 CS 和 IP 壓入棧中
    轉(zhuǎn)移

    call 指令不能實現(xiàn)短轉(zhuǎn)移.

    call 標號

    CPU 執(zhí)行此指令時, 執(zhí)行如下操作:

    (1) SP = SP - 2, SS * 16 + SP = IP
    (2) IP = IP + 16 位位移

    執(zhí)行 call 標號 指令相當于執(zhí)行:
    push IP
    jmp near ptr 標號

    call far ptr 標號

    CPU 執(zhí)行此指令時, 執(zhí)行如下操作:

    (1) SP = SP - 2, SS * 16 + SP = CS
    SP = SP - 2, SS * 16 + SP = IP
    (2) CS = 標號所在段的段基址
    IP = 標號在段中的偏移地址

    執(zhí)行 call far ptr 標號 指令相當于執(zhí)行:
    push CS
    push IP
    jmp far ptr 標號

    其他 call 指令

    當然轉(zhuǎn)移地址可以存儲在寄存器或者內(nèi)存中, 相應的語法如下:

    call reg

    reg 為16位寄存器
    相應 CPU 操作:
    SP = SP - 2, SS * 16 + SP = IP
    IP = reg 中的值
    相當于:
    push IP
    jmp reg

    call word ptr 內(nèi)存單元地址

    相當于:
    push IP
    jmp word ptr 內(nèi)存單元地址
    示例:
    mov sp, 10H
    mov ax, 0123H
    mov ds:[0], ax
    call word ptr ds:[0] // 執(zhí)行后 IP = 0123H, SP=0EH

    call dword ptr 內(nèi)存單元地址

    相當于:
    push CS
    push IP
    jmp dword ptr 內(nèi)存單元地址
    示例:
    mov sp, 10H
    mov ax, 0123H
    mov ds:[0], ax
    mov word ptr ds:[2], 0
    call word ptr ds:[0] // 執(zhí)行后 CS=0, IP = 0123H, SP=0CH

    call + ret

    建議在繼續(xù)往下看之前, 仔細閱讀一下上圖中代碼, 分析程序結(jié)束時 bx 中的值是多少?

    分析一下這個程序?qū)⒎浅S兄谖覀兝斫?call 和 ret 指令.

    (1) 程序執(zhí)行到 call s 時, IP 此時指向了 call s 的下一條指令 mov bx, ax (CS 和 IP 指向了 CPU 當前要讀取指令的地址. 而當前已經(jīng)執(zhí)行到了 call s,因此下一條要讀取的指令將是 mov bx, ax);
    (2) CPU 執(zhí)行 call s 時, 將當前 IP 值(指向 mov bx, ax 的偏移地址)壓棧, 并將 IP 的值改變?yōu)闃颂?s 的偏移地址.
    (3) CPU 從標號 s 處開始執(zhí)行指令, loop 循環(huán)結(jié)束后, ax = 8
    (4) CPU 將 ret 指令讀入, IP 指向了 ret 指令后的內(nèi)存單元(此時僅僅是讀取指令,還未執(zhí)行 ret 指令);
    (5) CPU 執(zhí)行 ret 指令, 從棧中彈出一個值(即 call s 指令先前壓入的 mov bx, ax 指向的偏移地址), 將該值存入 IP 中. 此時 CS:IP 指向指令 mov bx, ax.
    (6) 執(zhí)行完 ret 指令之后, 程序?qū)⑻D(zhuǎn)到 mov bx, ax 處繼續(xù)執(zhí)行, 直至完成.
    (7) 最終, bx = 8.

    歡迎交流任何想法.

    End…

    1

    總結(jié)

    以上是生活随笔為你收集整理的汇编学习笔记(二):转移指令的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。