从逻辑上讲,我想要做的是:
GLOBAL FRED
FRED EQU 5
在一个模块中,
EXTERN FRED
MOV ECX,FRED
一秒钟。
我知道
第一个模块
GLOBAL FRED
FRED: DD 5
第二个模块
EXTERN FRED
MOV ECX,[FRED]
非常愉快地工作,但我真正喜欢的是第一个版本。
我已经尝试了
FRED EQU 5
FRED: EQU 5
%define FRED 5
%assign FRED 5
无效 - 没有错误消息,但未导出标签。只有FRED
是地址才能合作。
那么 - 有没有办法将一个模块中的值作为常量导出,而不是地址?
答案 0 :(得分:2)
简短回答:不。
您不能使用equ,define或assign进行导出,因为它们不会在编译模块中显示为单独的值。它们只影响预处理器,所以写
FRED equ 5
mov ecx, FRED
实际编译为
mov ecx, 5
通常的做法是使用包含所有常量的C样式头文件,然后只在需要的地方包含头文件。
fred.asm:
%ifndef FRED_ASM
%define FRED_ASM
%define FRED 5
; ... other constants ...
%endif
module.asm
%include "fred.asm"
mov ecx, FRED
答案 1 :(得分:1)
如果我理解正确,您希望FRED在某处定义并被许多模块/源文件使用?每个模块/源文件使用FRED而不是更改每个源文件中的值并重新组装每个文件,只需更改一个FRED实例并让它在任何地方使用?如果是这种情况,您可以将equ
ates放入静态库并链接到它。这不适用于%define
,仅适用于equ
。
试试这个:
libequates.asm
global FRED, JOHN
FRED equ 5
JOHN equ 6
makefile for libequates.asm(根据需要进行修改)
LIBRARY = libequates
all: $(LIBRARY) PostMake
$(LIBRARY): $(LIBRARY).o
ar -cr $(LIBRARY).a $(LIBRARY).o
strip --strip-unneeded $(LIBRARY).a
$(LIBRARY).o: $(LIBRARY).asm
nasm -f elf64 $(LIBRARY).asm -F dwarf
PostMake:
mkdir -p ~/projects/lib/
mv $(LIBRARY).a ~/projects/lib
现在使用并测试它是否有效(为简单起见,我将使用printf
):
externs.asm
extern FRED, JOHN, printf, exit
global start
section .data
fmtint db "%d", 10, 0
section .text
start:
mov rsi, FRED
mov rdi, fmtint
xor rax, rax
call printf
mov rsi, JOHN
mov rdi, fmtint
xor rax, rax
call printf
mov rdi, 0
call exit
makefile for externs.asm
APP = externs
all: $(APP) clean
$(APP): $(APP).o
ld -o $(APP) $(APP).o -entry start -L ~/projects/lib -lequates -lc -dynamic-linker /lib64/ld-linux-x86-64.so.2
$(APP).o: $(APP).asm
nasm -f elf64 $(APP).asm -F dwarf
clean:
rm $(APP).o
并输出:
现在,您只需要在一个地方更改equate值,只重新组装静态库并重新链接您的程序/模块。
答案 2 :(得分:1)
Nasm将点字符("。")视为符号名称中的合法字符。 您可以使用它来伪造COM(组件对象模型)"对象属性"。 如果你有3个模块,每个模块都有一个"宽度"变量,你可以拉下面的特技:
;ButtonWidget
SECTION .data
global ButtonWidget.width, ButtonWidget.height
ButtonWidget:
.width dd 50
.height dd 10
;SelectWidget
SECTION .data
global SelectWidget.width, SelectWidget.height
SelectWidget:
.width dd 50
.height dd 100
;TextWidget
SECTION .data
global TextWidget.width, TextWidget.height
TextWidget:
.width dd 200
.height dd 10
在您的主模块中,
;GUIapp
extern ButtonWidget.width, ButtonWidget.height
extern SelectWidget.width, SelectWidget.height
extern TextWidget.width, TextWidget.height
%macro MakeChildWindow 4
push %1
push %2
push %3
push %4
call makechildwindow
%endmacro
MakeChildWindow 10, 10, ButtonWidget.width, ButtonWidget.height
MakeChildWindow 10, 30, SelectWidget.width, SelectWidget.height
MakeChildWindow 10, 200, TextWidget.width, TextWidget.height
该技术的优点是可以修复外部变量 或者是可变的,而且非常易读。