【问题标题】:Nested STRUCT and UNION in x86 assembly languagex86 汇编语言中的嵌套 STRUCT 和 UNION
【发布时间】:2018-11-17 21:53:14
【问题描述】:

我正在尝试用汇编语言为网络应用程序实现 c 数据结构。注意:这是一个汇编类项目,所以它需要在汇编程序中!!!

这是来自 MS 文档的 c 结构:

typedef struct in_addr {
    union {
        struct {
          UCHAR s_b1;
          UCHAR s_b2;
          UCHAR s_b3;
          UCHAR s_b4;
    } S_un_b;
    struct {
          USHORT s_w1;
          USHORT s_w2;
    } S_un_w;
        ULONG S_addr;
    } S_un;
} IN_ADDR, *PIN_ADDR, *LPIN_ADDR;

这是汇编语言代码:

in_addr STRUCT
    UNION S_un
        S_un_b STRUCT      ; an error here!
            s_b1 BYTE ? 
            s_b2 BYTE ?
            s_b3 BYTE ?
            s_b4 BYTE ?    
        S_un_b ENDS        ; an error here!

        S_un_w STRUCT      ; an error here!
            s_w1 WORD ? 
            s_w2 WORD ? 
        S_un_w ENDS        ; an error here!

        S_addr DWORD ? ; the complete address
    ENDS
in_addr ENDS

当我尝试构建时,我收到一条错误消息(参见上面的 cmets),它可能是语法错误(在前 3 种情况下)或最后一个是“不匹配的块嵌套”。我试图查看有关是否可以在联合中定义结构的英特尔文档,但我找不到任何确定的信息。

如果不是更多,我会非常感谢英特尔/MS 文档作为解决方案。我是汇编语言的新手,虽然奇怪的是它正在成为一种爱好。

【问题讨论】:

  • 你可能没有理由定义这个结构。只需使用 DWORD 直接存储 IPv4 地址。如果您确实需要访问构成 32 位地址的单个字或字节,那么您可以使用 BYTE PTR [ipaddr + 3] 之类的东西,就像使用内存中的任何其他 DWORD 值一样。
  • @RossRidge 如果是这样,那将非常简化!这就是我定义它的原因,请看一下并告诉我您的建议是否仍然有效:docs.microsoft.com/en-us/windows/desktop/api/iphlpapi/…。基本上,我想使用 SendARP 函数,其中 DestIP 和 SrcIP 的类型为 in_addr。
  • SendARP 函数需要指向内存中两个IPAddr 结构的指针,但结构和其他类型只是编译/汇编时的抽象。如果它期望指针指向内存中的两个 DWORD 值,那么编译后的代码将完全相同,因为它将使用相同的 32 位指令访问这两个值。同样,无论您使用in_addr 结构还是DWORD,您都会从汇编代码中生成相同的机器代码。
  • 这应该是我问的问题。 @RossRidge 谢谢!另一个类似的问题:我可以从汇编程序中调用 SendARP,还是需要包含一些文件?这是一个单独的问题,我意识到..
  • 没有任何内容可以包括在内。您需要使用 EXTERN 进行声明,并且可能需要将其命名为 _SendARP@16,因为与大多数 Windows API 函数一样,32 位版本使用 stdcall 调用约定。您还必须链接到iphlpapi.lib

标签: assembly struct x86 masm unions


【解决方案1】:

对于任何有类似问题的人,定义包含结构的联合的方式是预先定义结构。

这是我最初的:

in_addr STRUCT
    UNION S_un
        S_un_b STRUCT      
            s_b1 BYTE ? 
            s_b2 BYTE ?
            s_b3 BYTE ?
            s_b4 BYTE ?    
        S_un_b ENDS        

        S_un_w STRUCT     
            s_w1 WORD ? 
            s_w2 WORD ? 
        S_un_w ENDS        

        S_addr DWORD ? ; the complete address
    ENDS
in_addr ENDS

这不会编译,至少在 masm 中。以下是可以做的:

S_un_b STRUCT
    s_b1 BYTE ? 
    s_b2 BYTE ? 
    s_b3 BYTE ? 
    s_b4 BYTE ? 
S_un_b ENDS

S_un_w STRUCT
    s_w1 WORD ? 
    s_w2 WORD ? 
S_un_w ENDS

in_addr STRUCT
    UNION S_un
        S_un_b<>
        S_un_w<>
        S_addr DWORD ? ; the complete address
    ENDS
in_addr ENDS

要使用此结构,请使用常规结构操作:

例如:

; To set S_addr
mov <in_addr instance name>.<union_name>.S_addr, 0h

类似的原则可以应用于访问 BYTE 和 WORD。

希望这对有同样问题的人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-05
    • 2023-03-25
    • 1970-01-01
    • 2021-12-02
    • 1970-01-01
    • 2014-06-23
    • 1970-01-01
    • 2017-01-03
    相关资源
    最近更新 更多