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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

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

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

章節目錄

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

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

    轉移指令原理

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

    只修改 IP 的轉移行為稱為 段內轉移.
    同時修改 CS 和 IP 的轉移行為稱為 段間轉移.

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

    jmp 指令

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

    jmp short 標號

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

    示例:

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

    jmp far ptr 標號

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

    示例:

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

    其他 jmp 指令

    當然轉移地址可以存儲在寄存器或者內存中, 相應的語法如下:

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

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

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

    Note: 轉移指令,不僅僅可以向后跳轉, 亦可以向前跳轉.

    jcxz 指令

    該指令為有條件轉移指令. 所有有條件轉移指令都是短轉移.

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

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

    示例:

    loop 指令

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

    ret 和 retf 指令

    ret 指令用棧中的數據, 修改 IP 的值, 實現近轉移.
    retf 指令用棧中的數據, 修改 CS 和 IP 的值, 實現遠轉移.

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

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

    相當于: pop IP

    CPU 執行 retf 執行時, 進行如下四步操作:

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

    相當于:
    pop IP
    pop CS

    示例:

    ret 用法

    retf 用法:

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

    call 指令

    CPU 執行 call 指令時, 執行以下兩步操作:

    將當前的 IP 或者 CS 和 IP 壓入棧中
    轉移

    call 指令不能實現短轉移.

    call 標號

    CPU 執行此指令時, 執行如下操作:

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

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

    call far ptr 標號

    CPU 執行此指令時, 執行如下操作:

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

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

    其他 call 指令

    當然轉移地址可以存儲在寄存器或者內存中, 相應的語法如下:

    call reg

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

    call word ptr 內存單元地址

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

    call dword ptr 內存單元地址

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

    call + ret

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

    分析一下這個程序將非常有助于我們理解 call 和 ret 指令.

    (1) 程序執行到 call s 時, IP 此時指向了 call s 的下一條指令 mov bx, ax (CS 和 IP 指向了 CPU 當前要讀取指令的地址. 而當前已經執行到了 call s,因此下一條要讀取的指令將是 mov bx, ax);
    (2) CPU 執行 call s 時, 將當前 IP 值(指向 mov bx, ax 的偏移地址)壓棧, 并將 IP 的值改變為標號 s 的偏移地址.
    (3) CPU 從標號 s 處開始執行指令, loop 循環結束后, ax = 8
    (4) CPU 將 ret 指令讀入, IP 指向了 ret 指令后的內存單元(此時僅僅是讀取指令,還未執行 ret 指令);
    (5) CPU 執行 ret 指令, 從棧中彈出一個值(即 call s 指令先前壓入的 mov bx, ax 指向的偏移地址), 將該值存入 IP 中. 此時 CS:IP 指向指令 mov bx, ax.
    (6) 執行完 ret 指令之后, 程序將跳轉到 mov bx, ax 處繼續執行, 直至完成.
    (7) 最終, bx = 8.

    歡迎交流任何想法.

    End…

    1

    總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。