使用NASM组装下面的结构,我收到以下错误:
test.asm:65: error: TIMES value -228 is negative
即,值0x104
被解释为负数。
NASM中TIMES
前缀的count参数的最大大小是多少?如何仅使用“小”计数来初始化结构?
_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.
答案 0 :(得分:4)
您可以找到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
移动指定字段的宏这一事实。
AT宏的功能是利用TIMES前缀将装配位置提前到指定结构字段的正确位置,然后声明指定的数据。因此,结构字段的声明顺序必须与结构定义中指定的顺序相同。
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
的{{1}}大于结构($-..@12.strucstart)
中的偏移量。{
因此错误。
答案 1 :(得分:1)
在网络上找到的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
。
十六进制值0x104,您指定为TIMES
的计数参数,具有十进制表示260,我们看到32 - 260 = -228。
我不能说为什么NASM将0x104解释为-228(除了上面的计算),但它可能与进入结构的下一个字段有关。
但是,将MAX_PATH
的定义更改为260(在WIN32N.inc中),结构组合得很好。