前天,複習彙編時,看到jmp的short跳轉,跳轉範圍為[-128,127],馬上我想到jmp的near跳轉應該為[-32738,32767],並且我寫了乙個程式來測試這一想法,程式如下:
org 0100h
jmp label_start
[section .code16]
[bits 16]
label_start:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h
mov ax, 0b800h
mov gs, ax ;initial segment
mov di, (80*12+12)*2
mov byte[gs:di], 's'
jmp near label_test
times 65530 db 0
label_test:
add di, 2
mov byte [gs:di], 't'
jmp $
這個跳轉已經越界了,程式執行的結果(顯示s)表明這乙個結果,我又修改了times這條指令,將65530改為65000,重新編譯執行,結果卻出乎意料,列印了」st「,十分不解。甚至以為是nasm的bug,昨天在csdn發了乙個帖子,按回帖人的建議,我反彙編跟蹤了幾次。終於發現了問題的所在。修改前和修改後的jmp near label_test反彙編**分別如下,
0000001b e9faff jmp word 0x18
0000001b e9e8fd jmp word 0xfe06
可以看出第二次的目的位址的確為0xfe06,正確位址。jmp的near跳轉範圍到底是[-32768,32767]麼?從上面反彙編**可以看出端倪,0x1b+3+0xfffa=0x10018,但是ip為16位的,故高位的1會丟掉。但我們能說上面的結論錯了麼?若我們顯示指定為32位的段,則使用的是eip,故上式的1不會丟掉。注意的是32位是執行在保護模式下,上面的程式不能簡單修改[bits 32],通過寫乙個執行在保護模式下的**,發現其跳轉範圍還真不那麼容易確定。
這是在保護模式下的反彙編**0001039e e9f6ff jmp word 0x397。對於**如下:
jmp near label_down
label_test:
nop
mov byte [gs:(80*12+2)*2],'y'
jmp $
times 65530 db 0
label_down:
jmp near label_test
可以看出我們跳轉到識別符號label_test是成功的。這樣就發現我們跳轉的範圍不那麼簡單,或者沒有乙個定值,下一條指令的ip=ip當前值+3+16位的偏移這個表示式。雖然16位的偏移是無符號數,但存在越界問題。分析00001039eh+ffff fff6h+3=0000 10397h,:-),按道理這樣子eip=0000 10397,但是注意jmp near這條指令只有3個位元組,而這個偏移值的用兩個位元組表示,所以這裡成了jmp word 0x397,而eip=0x397,利用這一點我們的跳轉範圍實現了65530個位元組的跳轉。不過,別高興的太早,這裡是利用了這一點與編譯器相關的特點,我們不能說jmp near跳轉可以實現[-65536,65535]這個範圍,總結一下,jmp near 跳轉,nasm編譯器的做法是只要位址在0-65535這個範圍都能正確跳轉,原因應該是jmp near 用乙個word來表示跳轉位址。
乙個action跳轉到另乙個action如何傳參
畢業設計還在繼續,遇到問題,從乙個action跳轉到另乙個action如何傳參,也不算難題吧,就是以前沒有接觸過,上網搜搜,發現答案,request.setattribute 引數名 引數 request.getattribute 引數名 試了試,不可以。然後想了想,是否可以把它存在session裡...
規劃 近乙個月的規劃
雖說計畫不如變化快,但是制定乙個短期的計畫,能知道自己最近專心該做什麼 1.整理好mfc的常用類,常用api函式。整理在visualc 的第四本筆記本上。2.細心看完一本directx教程,ultimate.game.programming.with.directx allen.sherrod,70...
談談我近乙個半月的dp練習
首先十分感謝henry y提供的50道dp練習,鏈結在這 雖然現在只做了30多道題,剩下的題目還沒寫,想著以後留著複習來用,但是我對dp的理解比以前高出了不少,現在我來說說對dp的想法吧。目錄 一 動態規劃的本質,以及它的核心難點 如何判斷這題用dp來解 二 關於我做到的關於dp以外的技巧 一 動態...