在Mac中开发基于Nasm的64位汇编程序

我们大多数人接触汇编都是在windows平台中,基于Masm开发80x86汇编语言。但是现在CPU都是64位,寻址空间也不再是以前的2^20的1MB寻址范围,而是2^64的超大寻址范围。当时之所会引出段地址和偏移地址的概念,我个人认为主要原因是寄存器的位数与地址总线位数不一致,所以才需要 段地址x16+偏移地址的形式。现在的64位CPU寄存器是64位,地址总线也是64位,因此寻址可以使用绝对内存地址的形式。

这张图片是64位CPU的结构,因此在开发64寻址模式的汇编语言时,需要采用64位寻址。

在Mac中开发64位汇编程序需要使用到Nasm,这个是本人基于Nasm开发的一个64位调试程序,可以打印数据到控制台中。

SECTION .data

gupMsg: resb 100 ;显示内存区域          
gupMsgLen: equ $-gupMsg ;显示区域大小
gupMsgIndex: dd 0x0,0x0 ;记录显示的当前内存位置

tmpMsg1: dd 0x0,0x0,0x0,0x0; 临时内存区域
tmpMsg2: dd 0x0,0x0,0x0,0x0; 临时内存区域

SECTION .text
global _main


;将数字转化为Acsii编码
;输入rax,输出rax,rdx
LongToChar:
    push rbx
    push rbp
    push rsi
    push rcx

    mov rbx,tmpMsg1
    mov [rbx],rax
    mov rbp,tmpMsg2
    add rbp,15
    
    mov rsi,0
    mov cx,8
Ls: mov al,[rbx+rsi]
    mov ah,al
    and al,00001111b
    add al,0x30
    cmp al,0x39
    jna o1
    add al,0x7
o1: shr ah,0x4
    and ah,00001111b
    add ah,0x30
    cmp ah,0x39
    jna o2
    add ah,0x7
o2: mov byte [rbp],al
    dec rbp
    mov byte [rbp],ah
    dec rbp
    inc rsi
    loop Ls

    mov rbp,tmpMsg2
    mov rax,[rbp]
    mov rdx,[rbp+8]

    pop rcx
    pop rsi
    pop rbp
    pop rbx
    ret

;打印rax中内容,调试tag存放在r8中
LogLong:
    push rax
    push rdi
    push rsi
    push rdx
    push rbx
    push r9

    call LongToChar
    mov rbx,gupMsg
    mov rbp,gupMsgIndex
    mov rdi,[rbp]
    mov r9,0x0
    ;增添tag
    mov [rbx+rdi],r8
    add rdi,8
    add r9,8
    mov byte [rbx+rdi],','
    inc rdi
    inc r9
    ;增添寄存器说明
    mov dword [rbx+rdi],'rax='
    add rdi,4
    add r9,4
    mov word [rbx+rdi],'0x'
    add rdi,2
    add r9,2
    ;增添真实内容
    mov [rbx+rdi],rax
    add rdi,8
    add r9,8
    mov [rbx+rdi],rdx
    add rdi,8
    add r9,8
    mov byte [rbx+rdi],0x0a
    inc rdi
    inc r9
    mov [rbp],rdi

    ;传递数据到显存
    mov rax,0x2000004
    mov rdi,1
    mov rsi,gupMsg
    add rsi,[rbp]
    sub rsi,r9
    mov rdx,r9
    syscall

    pop r9
    pop rbx
    pop rdx
    pop rsi
    pop rdi
    pop rax
    ret

kernel:
    syscall
    ret

_main: 
    ;核心代码执行
    mov r8,'test1'   ;调试内容标题
    mov rax,0x11111  ;需要打印的调试内容
    call LogLong

    mov r8,'test2'   
    mov rax,rbx
    call LogLong

    mov rax,0x2000001
    mov rdi,0
    call kernel


使用nasm进行编译

/etc/nasm-2.12/nasm -f macho64 printf.nasm   

需要使用新版本的nasm,本人放到的/etc/nasm-2.12/目录下,原代码放到了printf.nasm中。下载最新版本的nasm可以到www.nasm.us下载。

之后再链接

ld -o printf -e _main printf.o

也可以将两个命令放到一起

/etc/nasm-2.12/nasm -f macho64 printf.nasm;ld -o printf -e _main printf.o  

./printf查看运行结果

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值