Assembly x64 Intro - Align 16 of Nasm

本文介绍了一个使用汇编语言实现的基本算术操作程序。通过定义宏指令简化打印过程,并演示了如何进行变量的16位对齐。此外,还展示了如何通过不同的算术指令来改变变量的值,并使用外部C函数进行输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



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位对齐了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值