NASM 中 TIMES 前缀的计数参数的最大大小?

Maximum size of count argument to TIMES prefix in NASM?

使用 NASM 组装下面的结构,我得到以下错误:

test.asm:65: error: TIMES value -228 is negative

即值 0x104 被解释为负数。

NASM 中 TIMES 前缀的计数参数的最大大小是多少?我如何仅使用 "small" 计数来初始化结构?

_stWin32FindData:
istruc WIN32_FIND_DATA
at WIN32_FIND_DATA.dwFileAttributes, dd 0x00
at WIN32_FIND_DATA.ftCreationTime, times 0x08 db 0x00
at WIN32_FIND_DATA.ftLastAccessTime, times 0x08 db 0x00
at WIN32_FIND_DATA.ftLastWriteTime, times 0x08 db 0x00
at WIN32_FIND_DATA.nFileSizeHigh, dd 0x00
at WIN32_FIND_DATA.nFileSizeLow, dd 0x00
at WIN32_FIND_DATA.dwReserved0, dd 0x00
at WIN32_FIND_DATA.dwReserved1, dd 0x00
at WIN32_FIND_DATA.cFileName, times 0x104 db 0x00
at WIN32_FIND_DATA.cAlternate, times 0x0e db 0x00 
iend

我使用 NASM 版本 2.12.02 @ Windows 10.

在网上找到的WIN32N.inc中,MAX_PATH定义如下:

...
DDD_RAW_TARGET_PATH equ 1h
DDD_REMOVE_DEFINITION equ 2h
DDD_EXACT_MATCH_ON_REMOVE equ 4h
MAX_PATH equ 32
MOVEFILE_REPLACE_EXISTING equ 1h
MOVEFILE_COPY_ALLOWED equ 2h
...

此外,WIN32_FIND_DATA.cFileName(在同一文件中找到的 WIN32_FIND_DATA 结构的一部分)被定义为大小为 MAX_PATH

您指定为 TIMES 的计数参数的十六进制值 0x104 具有十进制表示形式 260,我们看到 32 - 260 = -228。

我不能说为什么 NASM 将 0x104 解释为 -228(除了上面的计算),但它可能与继续结构的下一个字段有关。

然而,将 MAX_PATH 的定义更改为 260(在 WIN32N.inc 中),结构组装得很好。

您可以找到 NASM 来源 here

Grepping for "TIMES" 在 parser.c 上找到这些行:

result->times = value->value;
if (value->value < 0 && pass0 == 2) {
    nasm_error(ERR_NONFATAL, "TIMES value %"PRId64" is negative",
               value->value);
               result->times = 0;
}

这表明 TIMES 采用 64 位值,但是 调查 nasm.h 我们发现

typedef struct insn { /* an instruction itself */
    char            *label;                 /* the label defined, or NULL */

    ...

    int32_t         times;                  /* repeat count (TIMES prefix) */
    bool            forw_ref;               /* is there a forward reference? */

    ...
} insn;

将参数的大小设置为 32 位。


然而,您面临的问题来自于 AT 是一个隐式使用 TIMES 来移动指定字段的宏。

The function of the AT macro is to make use of the TIMES prefix to advance the assembly position to the correct point for the specified structure field, and then to declare the specified data. Therefore the structure fields must be declared in the same order as they were specified in the structure definition.

这就是AT的实现方式

istruc teststruc2
 at .word, db 5
iend

..@12.strucstart:
  times (.word-teststruc2)-($-..@12.strucstart) db 0
  db 5

正如@Nze 所说,WIN32_FIND_DATA.cFileName 定义为 TCHAR cFileName[MAX_PATH]MAX_PATH 是 32。
由于您定义的 cFileName 太大,因此 AT WIN32_FIND_DATA.cAlternate($-..@12.strucstart) 大于其在结构 (.word-teststruc2).
中的偏移量 因此错误。