【问题标题】:Assembly - Structure装配 - 结构
【发布时间】:2017-09-01 06:36:39
【问题描述】:

Employee STRUCT

    IdNum BYTE "000000000" ; 9 
    LastName BYTE 30 DUP(0) ; 30
    ALIGN WORD ; 1 byte added
    Years WORD 30 ; 2
    ALIGN DWORD ; 2 byte added
    SalaryHistory DWORD 0,0,0,0 ; 16
Employee ENDS


employees Employee 5 DUP (<"123456789","AAAAAAAA",30h,4 DUP(0EEEEEEEEh)>)

当我使用时

mov eax,TYPE Employee ; it says used 60byte space

但是当我在内存上看到它说使用 57 字节空间

mov esi,SIZEOF Employee;
mov eax,employees[esi].Years

所以如果我使用该语句,我永远不会得到正确的值。 但是如果我将 057h 移动到 esi,我可以得到正确的值,即 30h,为什么?

但是让我们尝试一些代码...

mov esi,TYPE 员工;也就是说 12 月 60 日

mov ax, employees[esi].Years ;这永远不会得到正确的价值


如果我不使用对齐,那将是正确的


mov esi,TYPE Employee ;这是 57 dec mov ax,employees[esi].Years ;会得到正确的值 FF

mov esi,0 mov eax,0 mov ax, employees[esi].Years ; AX = 0xFF

是的,它绝对是正确的值,因为从基指针...尝试编译 mov esi,TYPE employee

使用 align 将无法获得正确的值,如果没有 align on struct 我可以获得正确的值...我尝试了将近 1 天来获取此信息

谁能告诉我正确的原因?

【问题讨论】:

  • 我无法完全理解您的问题。无论如何,您是否考虑过填充?
  • 您的问题几乎没有差异,这使得如果不实际使用自己的 MASM(我没有)就很难理解。如果ALIGNSTRUCT 中起作用,那么偏移量应该是IdNum=0, LastName=9, Years=40 (39+1), SalaryHistory=44 (42+2), ENDS=60 (顺便说一句,第二个对齐只做+2,而不是+3,因为WORD 是2B)。但是我不明白你是如何以内存视图结束的,其中年份0x30 位于偏移量39,这就像ALIGN 根本不起作用,或者你的填充DUP 是错误的。 qwords 的内存视图令人困惑,请字节视图?
  • 再看一下那个内存视图,你的屏幕必须由与问题不同的源代码创建。如果Years BYTE,那么没有对齐的Years 可以在偏移量39,SalaryHistory 可以是40,并且40+16 = 56,这将是有意义的。minimal reproducible example 可能会有所帮助(对于有MASM 和 VS,不适合我)。
  • Years WORD 30 ; 1 - 我不这么认为 :-) 最后我检查了一下,一个单词是 两个 字节。
  • 对不起,我忘记编辑了,因为我在我的 MASM 上编辑,没有重新写过,谢谢

标签: assembly x86


【解决方案1】:

我也对此进行了测试,只需填写 LastName 字段的所有 30 个字符,只需稍作改动。移动到 EDX 的 SIZEOF 值确实是 0x3C(十进制 60),它考虑了结构定义中的 ALIGN 语句。但是当您在 Debug Memory 窗口中检查初始化结构时,employees 数组的每个实例仅占用 0x39 字节(十进制 57)。这是我的源代码,显示了字段的十六进制偏移量:

底线:当您使用字段初始值设定项声明结构实例时,ALIGN 指令似乎对数据对齐没有影响。

Employee STRUCT                            
 IdNum BYTE "000000000"                
 LastName BYTE 30 DUP(0)               
 ALIGN WORD                           
 Years WORD 30                         
 ALIGN DWORD                          
 SalaryHistory DWORD 0, 0, 0, 0        
Employee ENDS

.data
employees Employee 5 DUP(<"111111111", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 0FFh, 4 DUP(0EEEEEEEEh)>)
; hex offsets:  00--08, 09-26, 27-28, 29-38.


.code
main proc
mov eax,offset employees
mov edx,SIZEOF Employee    ; 0x3C

好消息是,以下语句正确地将“Years”的值加载到 AX 寄存器中:

mov esi,0
mov eax,0
mov ax, employees[esi].Years         ; AX = 0xFF

【讨论】:

  • 您好先生,我很高兴您对我的帖子发表评论,但让我们试试您的代码... mov esi,TYPE employee ;这是 12 月 60 日,它在你的书 mov ax, employees[esi].Years 上说索引号 1;如果我不使用对齐,这将永远不会得到正确的值,这将是正确的 ---- mov esi,TYPE Employee ;这是 57 dec mov ax,employees[esi].Years ;会得到正确的值 FF
【解决方案2】:

由作者 Kip Irvine 回答:

看起来我们应该避免在结构定义中使用ALIGN

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 2021-12-03
    • 2015-11-06
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    相关资源
    最近更新 更多