您的位置:首页 > 其它

Assembly x64 Intro - Align 16 of Nasm

2015-12-10 13:36 453 查看

1. addr.S

extern printf ; the C function to be called

%macro pabc 1 ; a "simple" print macro

section .data

.str db %1,0 ; %1 is first actual in macro call

section .text

mov rdi, fmt4 ; first arg, format

mov rsi, .str ; second arg

mov rdx, a ; a' address rather than its value

mov rcx, b ; b' address rather than its value

mov r8, [c] ; fifth arg

mov rax, 0 ; no xmm used

call printf ; Call C function

%endmacro

section .data ; preset constants, writable

align 16

a: dq 3 ; 64-bit variable a initialized to 3

b: dq 4 ; 64-bit variable b initializes to 4

fmt4: db "%s, a=%p, b=%p, c=%ld",10,0 ; format string for printf

section .bss ; uninitialized space

c: resq 1 ; reserve a 64-bit word

section .text ; instructions, code segment

global main ; for gcc standard linking

main: ; label

push rbp ; set up stack

lit5: ; c=5;

mov rax,5 ; 5 is a literal constant

mov [c],rax ; store into c

pabc "c=5 " ; invoke the print macro

addb: ; c=a+b;

mov rax,[a] ; load a

add rax,[b] ; add b

mov [c],rax ; store into c

pabc "c=a+b" ; invoke the print macro

subb: ; c=a-b;

mov rax,[a] ; load a

sub rax,[b] ; subtract b

mov [c],rax ; store into c

pabc "c=a-b" ; invoke the print macro

mulb: ; c=a*b;

mov rax,[a] ; load a (must be rax for multiply)

imul qword [b] ; signed integer multiply by b

mov [c],rax ; store bottom half of product into c

pabc "c=a*b" ; invoke the print macro

diva: ; c=c/a;

mov rax,[c] ; load c

mov rdx,0 ; load upper half of dividend with zero

idiv qword [a] ; divide double register edx rax by a

mov [c],rax ; store quotient into c

pabc "c=c/a" ; invoke the print macro

pop rbp ; pop stack

mov rax,0 ; exit code, 0=normal

ret ; main returns to operating system

2. compile

nasm -f elf64 addr.S

gcc -o addr.x addr.o

3. run

./addr.x

c=5 , a=0x601040, b=0x601048, c=5

c=a+b, a=0x601040, b=0x601048, c=7

c=a-b, a=0x601040, b=0x601048, c=-1

c=a*b, a=0x601040, b=0x601048, c=12

c=c/a, a=0x601040, b=0x601048, c=4

可以看到, a 的地址是 16 位对齐的, 而 b 的 不是。

4. 修改代码, 设置 b align 16 属性

section .data ; preset constants, writable

align 16

a: dq 3 ; 64-bit variable a initialized to 3

align 16

b: dq 4 ; 64-bit variable b initializes to 4

fmt4: db "%s, a=%p, b=%p, c=%ld",10,0 ; format string for printf

5. 重新编译运行

c=5 , a=0x601040, b=0x601050, c=5

c=a+b, a=0x601040, b=0x601050, c=7

c=a-b, a=0x601040, b=0x601050, c=-1

c=a*b, a=0x601040, b=0x601050, c=12

c=c/a, a=0x601040, b=0x601050, c=4

现在可以看到, a, b 的地址都是 16位对齐了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: