作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想学习一种指定通用寄存器参数大小的方法。
例如:
%macro lalala 1
mov word [buff], %1w
%endmacro
它仅适用于
r8
-
r15
,但我想为他们所有人使用这个宏
rax
-
rdx
,
rdi
,
rsi
,
r8
-
r15
.
最佳答案
我将两个 NASM 预处理器宏放在一起,它们组合在一起允许您将任何寄存器名称(任何大小)作为输入以及大小,并将其转换为给定大小的适当寄存器名称。这些宏根本不使用我提到的 altreg
寄存器名称 ( documented in the NASM manual here )。不过,可以毫不费力地添加将 r0
输入到 r7
的兼容性。以下是完整的宏:
%imacro regindexdef 2.nolist
%push
%define _%1 256
%assign %$size 0
%assign %$exit 0
%rep 5
%ifn %$exit
%if %$size == 0
%define %$regnames "ah ch dh bh "
%elif %$size == 1
%define %$regnames "al cl dl bl spl bpl sil dil r8b r9b r10br11br12br13br14br15b"
%elif %$size == 2
%define %$regnames "ax cx dx bx sp bp si di r8w r9w r10wr11wr12wr13wr14wr15w"
%elif %$size == 4
%define %$regnames "eax ecx edx ebx esp ebp esi edi r8d r9d r10dr11dr12dr13dr14dr15d"
%elif %$size == 8
%define %$regnames "rax rcx rdx rbx rsp rbp rsi rdi r8 r9 r10 r11 r12 r13 r14 r15 "
%endif
%assign %$index 0
%rep 16
%ifn %$exit
%substr %$reg %$regnames %$index * 4 + 1, 4
%deftok %$reg %$reg
%ifnempty %$reg
%ifidni %$reg, %2
%assign _%1 %$index
%assign %$exit 1
%exitrep
%endif
%endif
%endif
%assign %$index %$index + 1
%endrep
%if %$exit
%exitrep
%endif
%assign %$size !%$size + %$size * 2
%endif
%endrep
%ifn %$exit
%error Invalid register name: %2
%endif
%pop
%endmacro
%imacro regsizedef 3.nolist
%push
%define _%1 invalidregister
%assign %$size 0
%assign %$highbyte 0
%ifidni %2, byte
%assign %$size 1
%elifidni %2, highbyte
%assign %$size 1
%assign %$highbyte 1
%elifidni %2, word
%assign %$size 2
%elifidni %2, dword
%assign %$size 4
%elifidni %2, qword
%assign %$size 8
%else
%assign %$size %2
%endif
%if %$size == 0
%error Invalid register size: %2
%else
%ifnnum %3
%error Invalid register number: %3
%elif (%3) >= 16
%error Invalid register number: %3
%elif (%3) < 0
%error Invalid register number: %3
%else
%if %$size == 1 && %$highbyte
%define %$regnames "ah ch dh bh "
%elif %$size == 1
%define %$regnames "al cl dl bl spl bpl sil dil r8b r9b r10br11br12br13br14br15b"
%elif %$size == 2
%define %$regnames "ax cx dx bx sp bp si di r8w r9w r10wr11wr12wr13wr14wr15w"
%elif %$size == 4
%define %$regnames "eax ecx edx ebx esp ebp esi edi r8d r9d r10dr11dr12dr13dr14dr15d"
%elif %$size == 8
%define %$regnames "rax rcx rdx rbx rsp rbp rsi rdi r8 r9 r10 r11 r12 r13 r14 r15 "
%else
%define %$regnames ""
%endif
%substr %$reg %$regnames (%3) * 4 + 1, 4
%deftok %$reg %$reg
%ifempty %$reg
%error Invalid register type selected
%else
%xdefine _%1 %$reg
%endif
%endif
%endif
%pop
%endmacro
以下是一些使用宏的有效示例:
bits 64
regsizedef REG, 2, 0
mov _REG, 1234h
; mov to ax
regsizedef REG, 4, 0
mov _REG, 12345678h
; mov to eax
regsizedef REG, qword, 0
%warning REG=>>_REG<<
; rax
regsizedef REG, highbyte, 2
%warning REG=>>_REG<<
; dh
regindexdef INDEX, rdi
regsizedef REG, word, _INDEX
mov _REG, 1234h
; mov to di
regindexdef INDEX, cx
regsizedef REG, qword, _INDEX
%warning REG=>>_REG<< INDEX=>>_INDEX<<
; reg rcx, index 1
我还上传了一个文件,包括宏、有效的测试用例和一些无效的测试用例:
https://ulukai.org/ecm/20201207.txt (需要
https://hg.ulukai.org/ecm/lmacros/ 的 lmacros )
%macro lalala 1
regindexdef INDEX, %1
regsizedef REG, word, _INDEX
mov word [buff], _REG
%endmacro
关于assembly - 如何在宏中指定寄存器大小(b/w/d),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65180767/
我是一名优秀的程序员,十分优秀!