将内容从.data部分移动到NASM中注册

时间:2015-09-16 11:56:31

标签: macos assembly nasm x86-64

我是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

2 个答案:

答案 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 printfexit函数。虽然编译器不同,但使用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