gpt4 book ai didi

assembly - 如何在宏中指定寄存器大小(b/w/d)

转载 作者:行者123 更新时间:2023-12-03 23:01:56 24 4
gpt4 key购买 nike

我想学习一种指定通用寄存器参数大小的方法。
例如:

%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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com