我是NASM的新手,并且很难将变量的内容从.data部分移动到注册。以下代码输出"值:0"代替"价值:1"。如果我写常量来直接注册(mov qword rax, 25
),一切正常。
; /usr/local/bin/nasm -f macho64 sum.asm && ld -macosx_version_min 10.7.0 -lSystem -o sum sum.o && ./sum
section .data
myvar: dq 1234
message: db "Value: %i", 10, 0
.len: equ $ - message
global start
extern _printf
extern _exit
section .text
start:
default rel
; This outputs "Value: 0"
mov qword [myvar], 1
mov rax, [myvar]
; This works:
; mov qword rax, 25
; Output
mov rsi, rax
mov qword rax, 0
lea rdi, [rel message]
call _printf
mov qword rax, 0
call _exit
/usr/local/bin/nasm -v
说:
NASM version 2.11.08 compiled on Mar 10 2015
答案 0 :(得分:1)
OS X NASM 2.11.08 bug再次袭击。使用旧版本(如2.11.06)或更新版本以及数据部分中相对符号寻址的修复程序。或者使用yasm
。
就像我在评论中所说,你可以用xor eax, eax
归零64位寄存器。这是标准的习语。
写入32位寄存器总是清除64位寄存器的upper32。与移动64位立即数相比,这节省了大量指令字节。
mov qword rax, 25
仍然是32位立即行动。 qword
是不必要的。该指令确实有一个不需要的REX前缀,使其成为64位写入,而不是通过写入低32来自动清除高电平32。
mov eax, 25
执行相同的操作,但指令字节数较少。
答案 1 :(得分:0)
您的代码是正确的,除了需要的全局入口点main
(但不是必需的,您可以使用链接选项调整入口点)。在这里,您要链接 libc printf
和exit
函数。虽然编译器不同,但使用printf
而不是_printf
可以提供帮助。
只有那些语义更改(并在Linux而不是Mac上编译),您的代码会提供所需的输出:
section .data
myvar: dq 1234
message: db "Value: %i", 10, 0
.len: equ $ - message
global main
extern printf
extern exit
section .text
main:
default rel
; This outputs "Value: 0"
mov qword [myvar], 1
mov rax, [myvar]
; Output
mov rsi, rax
mov qword rax, 0
lea rdi, [rel message]
call printf
mov qword rax, 0
call exit
<强>编译强>
$ nasm -felf64 -o obj/label64.o label64.asm
$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib64/crt1.o \
/usr/lib64/crti.o obj/label64.o /usr/lib64/crtn.o -lc -o bin/label64
<强>输出强>
$ ./bin/label64
Value: 1
注意:您可能需要调整link命令所需的路径。否则,您只需拨打gcc
并让它对路径进行排序。 E.g:
$ gcc -o bin/label64 obj/label64.o