2013-11-21 41 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

相关问题