ASM JUMP指令和C/C++中的指针有什么主要区别?

4

我在ASM和C/C++方面是新手。许多网站向我展示了一张图片,不仅指针“指向”它们存储的某个地方(地址),而且还有跳转。请问有人能告诉我“ASM跳转指令和C/C++中指针的主要区别是什么”。谢谢大家。


8
它们的主要区别在于它们是完全不同的概念。一个存储地址,另一个告诉处理器从一个地址开始执行代码。 - Mike Seymour
是的,值与流程控制不同,谢谢。但是如果“指针是表示地址的值”,那么如何“指向”该地址呢?您能否给我一些关于它如何工作的信息? - erafraw
你是什么意思,指针如何指向?它包含一个地址,并且被认为指向该地址处的任何对象。 - Mike Seymour
谢谢您的帮助!现在我认为我应该问的真正问题是,“指针操作被翻译成汇编指令吗?” - erafraw
1
跳跃是一个动词,指针是一个名词。例如,您可以跳转到存储在函数指针中的地址,但指针本身只是一个数字,它什么也不做。指针操作如何转换为汇编取决于操作是什么。这些操作被转换为指令。 - wrosecrans
显示剩余2条评论
2个回答

6

指针用于存储变量的地址。

处理器使用 ASM JUMP 来从地址开始执行代码。

我认为没有任何相关的理由来区分这两个概念,因为它们都是不同的概念,用于不同的原因。


是的,但我只想知道C++指针在汇编代码中是如何工作的。 - erafraw
3
在汇编代码中(假设是由编译器生成的代码),指针工作原理与跳转指令无关。建议您编写一些使用指针的C或C ++代码,让编译器生成汇编清单,并研究指针操作是如何被转换为汇编指令的。如果您在此之后有更加 具体 的问题,请将其发布为新问题。 - Keith Thompson

3
它们并不相似,指针只是地址,它们在c/c++中似乎具有神秘性,但在汇编语言中,指针可能是一个带有存储在其中的地址的寄存器,该地址“指向”某些数据,EIP是一个指向程序执行期间当前指令的指针,整个想法是,复制指向数据的地址比数据本身更“便宜”。
我认为混淆的原因是c/c++是强类型语言,而汇编是弱类型语言。
这篇关于强类型和弱类型的维基百科文章说明了这一切,它对指针的解释如下: 指针 一些编程语言将指针公开为数字值,并允许用户对其进行算术运算。这些语言有时被称为“弱类型”,因为指针算术可以用于规避语言的类型系统。 即使如此,如果阅读这个指针教程,它说:
a[5] = 0;       // a [offset of 5] = 0
*(a+5) = 0;     // pointed by (a+5) = 0

这两个表达式是等价的,当你思考它们时就会感到很有道理。
在汇编语言中,a只是指向一个数组的指针,你可能会有类似于以下的东西;
.data

   a db  "some data"

.data是指向数据所在地址的指针。a:也是一个指针,指向程序中定义字节's'之前标签a所在的地址,就像c语言中的指针一样。

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命令将test.c文件转换为汇编语言,命令为:gcc -S -masm=intel -fno-asynchronous-unwind-tables -fno-dwarf2-cfi-asm test.c,生成的汇编文件是test.s

    .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

您使用哪个调试器或汇编器? - erafraw
我在Windows和Linux上都使用并喜爱gdb(即GNU调试器)。我使用的语言是Windows:MASM,NASMLinux:NASM - James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接