2015-10-14 64 views
0

一个字符串表示为一个char数组。例如,如果我在地址0x80000000处有一个字符串“abcdef”,是否正确?如何在IA32程序集中表示一个字符串?

0x80000008 
0x80000004: 00 00 46 45 
0x80000000: 44 43 42 41 

(在栈,它生长下来,我有地址减少)

+0

是的。但是,不要问这里,通过询问C编译器的汇编程序输出(如果使用[GCC](http://gcc.gnu),可以检查gcc -Wall -fverbose-asm -O')。 org /)或通过查看调试器('gdb') –

+2

这不是汇编,这只是一个内存转储 –

+0

嗯,所以41的地址是0x8000000,而44的地址是0x80000003? –

回答

4
  1. 较低的地址总是先 - 即使是在堆栈中。所以你的例子应该是:

    80000000: 41 42 43 44 
    80000004: 45 46 00 00 
    
  2. 你的例子实际上是字符串:“ABCDEF”。字符串 “ABCDEF” 应该是:

    80000000: 61 62 63 64 
    80000004: 65 66 00 00 
    

另外,在存储器转储,默认基数为16(十六进制),所以 “0X” 是多余的。请注意,字符代码也是十六进制的。例如,字符串 “JKLMNOP” 将是:

80000000: 4A 4B 4C 4D 
    80000000: 4E 4F 50 00 
  • 无字符串通常放置在栈中。只在数据存储器中。有时在堆栈中放置指向字符串的指针,即字符串的起始地址。

  • 你的(和我的)例子涉及所谓的ASCII编码。但有很多可能的character encoding方案。例如EBCDIC也使用8位代码,但不同于ASCII。

  • 但是,8位代码不是强制性的。例如UTF-32使用32位代码。此外,固定代码大小并不是强制性的。 UTF-8使用1到6个字节的可变代码大小,具体取决于编码的字符。

    +0

    在栈协议,它向下增长(当推动地址被减去时),因此地址更高,在这种情况下应该如何考虑? –

    +0

    而且栈也是内存权利的一部分(虚拟内存)? –

    +0

    1.我总是喜欢假设内存有开始(地址0)和结束(地址fffff ...),开始位于屏幕/工作表的顶部,结束位于底部,堆栈实际上不增长(好吧,它会增长,但它是一个副作用,而不是重要的T)。栈顶,向后移动 - 朝向较低地址。堆栈开始位于内存的底部。 :) 2.堆栈当然是内存,但作为一个堆栈它有一些特殊用途,并且字符串数据通常不会被放置在堆栈本身中。 (局部变量是另一次谈话的特例)。 – johnfound

    0

    这实际上并不是组装。你可以通过运行gcc-S来得到一个例子。传统上在x86汇编中,你会声明一个标签后跟一个字符串,该字符串将被声明为db(数据字节)。如果它是C风格的字符串,则会跟着db 0。现代汇编器有一个asciiz类型,可以自动添加零字节。如果它是一个Pascsl样式的字符串,它将在其前面是一个包含其大小的整数。这些将在内存中连续布局,并且您将通过使用标签来获取字符串的地址,这与您如何从标签中获取分支目标的地址类似。

    您将使用哪个选项取决于您将要使用的选项。如果你传递给C标准库函数,你可能需要一个C风格的字符串。如果您打算使用write()send()来编写它,并将其复制到具有边界检查的缓冲区中,则可能需要显式地存储其长度,即使系统或库调用不再使用该格式。好的,安全的代码也不应该使用strcpy()。但是,您可以同时存储长度和空字符串。

    MS-DOS使用的一些旧代码字符串以$结尾,这是一种从CP/M复制的与Z80上的8位代码兼容的约定。在操作系统中有一大堆这些遗留物直到Windows ME。

    相关问题