如何在IA32汇编中表示字符串?

时间:2015-10-14 04:41:04

标签: c assembly

字符串表示为char数组。例如,如果我在地址0x80000000处有一个字符串“abcdef”,则以下是否正确?

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

(在堆栈中,它会逐渐减少,因此我的地址会减少)

2 个答案:

答案 0 :(得分:5)

  1. 较低的地址始终是第一个 - 即使在堆栈中也是如此。所以你的榜样应该是:

    80000000: 41 42 43 44 
    80000004: 45 46 00 00
    
  2. 您的示例实际上是字符串:" ABCDEF"。字符串" abcdef"应该是:

    80000000: 61 62 63 64
    80000004: 65 66 00 00 
    
  3. 此外,在内存转储中,默认基数为16(十六进制),因此" 0x"是多余的。请注意,字符代码也是十六进制的。例如字符串" JKLMNOP"将是:

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

    2. 您(和我的)示例涉及所谓的ASCII编码。但是有许多可能的character encoding方案可能。例如,EBCDIC也使用8位代码,但不同于ASCII。

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

答案 1 :(得分:0)

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

您将使用哪个选项取决于您将使用它做什么。如果您要传递给C标准库函数,您可能需要一个C风格的字符串。如果您要用write()send()编写它并将其复制到带边界检查的缓冲区,您可能希望显式存储其长度,即使没有系统或库调用使用该格式更多。好的,安全的代码也不应该使用strcpy()。但是,您可以存储长度并使用null终止字符串。

MS-DOS的一些旧代码使用以$终止的字符串,这是一种从CP / M复制的约定,用于与Z80上的8位代码兼容。在Windows ME中,操作系统中有许多这些遗产。

相关问题