2013-11-21 75 views
3

我是ASM和C/C++的新手。許多網站向我展示了一張圖片,不僅指針指向他們存儲的某處(地址)而且Junm。請有人告訴我知道「ASM JUMP指令和C/C++指針之間的主要區別是什麼」。多謝你們。ASM JUMP指令和C/C++指針之間的主要區別是什麼

+7

的主要區別是,它們是完全不同的概念。一個存儲地址,另一個告訴處理器開始執行地址代碼。 –

+0

你的意思是指針比跳轉高,當編譯器從C++生成Asm代碼時,所以指針可以生成一個或多個跳轉,是嗎? – erafraw

+0

不,我的意思是它們是完全不同的東西,無法進行有意義的比較。指針是一個表示地址的值 - 它不會生成任何指令,跳轉或其他。編譯器生成跳轉指令(以及類似的),以使流控制代碼像循環和函數調用一樣工作。 –

回答

2

它們並不相似,指針只是地址,由於抽象的原因,它們在c/C++中可能看起來很神祕,但是在彙編中指針可能是一個寄存器,其中存儲的地址可以「指向」某些數據,EIP是在程序執行期間「指向」當前指令的指針,整個想法是複製指向數據的地址比數據本身「更便宜」。

我認爲混淆來自於這樣的事實,即c/C++是強類型語言,程序集是鬆散類型的。

wiki article的強類型可以解釋這一切,它是這樣說的指點一下..

指針

有些編程語言暴露指針,好像他們是數值,並允許用戶對它們執行算術運算。這些語言有時被稱爲「弱類型」,因爲指針算術可以用來繞過語言的類型系統。

即使這樣說,如果你讀這tutorial on pointers它說;

a[5] = 0;  // a [offset of 5] = 0 
*(a+5) = 0;  // pointed by (a+5) = 0 

這兩個表達式是等價的,當你考慮它時是有意義的。

a只是一個數組的指針,你可能有一些粗略的東西,

.data 

    a db "some data" 

.data是指向所在的地址數據存在 a:也是一個指針地址開始身在何方標籤一個是在程序只是"some data"字節's'定義之前一樣,如果c中的指針a是;

char a[] = "some data"; // or 
char *a = "some data"; // and a is the start address 

訪問它們看起來像;

a[5] == 'd' && *(a+5) == 'd'; // true 

指向一個看起來像;

char *b = a; 

訪問在彙編中看起來像這樣;

mov al, byte[a+5] // calculates effective address or points to the 'd' 
cmp al, 'd' // if al == 'd' 
je some_appropriate_label // je(jump if equal) somewhere anywhere 

//(some_appropriate_label being an address or pointer to the begining of some appropriate code) 

指向或獲取彙編中的地址看起來像是;

mov ebx, a // moves the address that a represents into ebx 
mov bl, byte[ebx+5] // moves 'd' into bl 

在彙編中,一切都非常暴露。


我覺得你爲你做了一些額外的調查,我做了這個簡單的c程序稱爲test.c;

int main(){ 
    char *pointer1 = "some data"; 
    char *pointer2 = pointer1; 
} 

並供給gcc -S -masm=intel -fno-asynchronous-unwind-tables -fno-dwarf2-cfi-asm test.c通過gcc得到test.s組件等效的test.c這是文件;

.file "test.c" 
    .intel_syntax noprefix 
    .def ___main; .scl 2; .type 32; .endef 
    .section .rdata,"dr" 
LC0: 
    .ascii "some data\0" 
    .text 
    .globl _main 
    .def _main; .scl 2; .type 32; .endef 
_main: 
    push ebp 
    mov ebp, esp 
    and esp, -16 
    sub esp, 16 
    call ___main 
    mov DWORD PTR [esp+12], OFFSET FLAT:LC0 
    mov eax, DWORD PTR [esp+12] 
    mov DWORD PTR [esp+8], eax 
    leave 
    ret 
    .ident "GCC: (rev2, Built by MinGW-builds project) 4.8.1" 

注意這些部分;

LC0: 
    .ascii "some data\0" 

call ___main 
mov DWORD PTR [esp+12], OFFSET FLAT:LC0 
mov eax, DWORD PTR [esp+12] 
mov DWORD PTR [esp+8], eax 

它看起來像這樣的程序正在使用的堆棧來存儲它的指針,esp是堆棧指針,它包含了地址或指針到堆棧的頂部在任何時間。

指針1

mov DWORD PTR [esp+12], OFFSET FLAT:LC0 // moves address where data lives into stack 
// this is where pointer1 lives 

指針2

mov eax, DWORD PTR [esp+12] // moves address/pointer into eax from stack 
mov DWORD PTR [esp+8], eax // moves address/pointer into pointer2 
// esp+12 is the c pointer (think *(a+0) a[0] from c but instead of char 's' it's an address(dword), 
// LCO is the data that was moved into the pointer which is also an address 

// The second line is basically saying; 
// move the 4byte address to the topOfStack+8bytes 
+0

你使用哪個調試器或彙編程序先生? – erafraw

+0

我在Windows和Linux上都使用並且喜歡'gdb a.k.a GNU Debugger'。和我使用'windows:masm,nasm'和'linux:nasm'的語言 – James

6

指針用於存儲變量的地址。

ASM JUMP被處理器用來從地址開始執行代碼。

我不認爲有任何相關的理由來區分兩者,因爲他們都是不同的概念,並用於不同的原因。

+0

是的,但我只想知道C++指針如何在Asm代碼中工作 – erafraw

+3

@erafraw:指針在彙編代碼中工作的方式(大概是由編譯器生成的代碼)與JUMP指令無關。我建議你編寫一些用戶指針的C或C++代碼,讓你的編譯器生成彙編列表,並研究指針操作如何轉換爲彙編指令。如果你之後有更多*特定*問題,我建議將它作爲一個新問題發佈。 –

+0

謝謝你,先生。這個好主意 – erafraw

相關問題