汇编学习(3),ddd以及跳转循环

2022-12-02 16:53:41 浏览数 (2)

本篇介绍

本篇先介绍一个GUI工具,用来查看寄存器和内存,再介绍下代码跳转。

DDD

首先先安装之:

代码语言:javascript复制
sudo apt install ddd

再写一段如下的代码:

代码语言:javascript复制
    ;; hello.asm
    section .data
    bNum db 123
    wNum dw 12345
    dNum dd 1234567890
    qNum1 dq 1234567890123456789
    qNum2 dq 123456
    qNum3 dq 3.14

    section .bss

    section .text

    global main

main:
    push rbp
    mov rbp, rsp
    mov rax, -1
    mov al, byte [bNum]
    xor rax,rax
    mov al,byte [bNum]
    mov rax, -1
    mov ax, word [wNum]
    xor rax,rax
    mov ax, word [wNum]
    mov rax, -1
    mov eax, dward [dNum]

    mov rax, -1
    mov rax, qword [qNum1]
    mov qword [qNum2], rax

    mov rax, 123456
    movq xmm0, [qNum3]

    mov rsp,rbp
    pop rbp
    ret

保存成 hello.asm, make后执行ddd hello,结果如下:

image.png

可以发现ddd 就是带有GUI的gdb,先在main上打个断点,点击run,这时候就会停到main上。

image.png

执行到第20行会发现一个问题,将bNum赋值给al了,可是rax的值是0xffffffffffffff7b ,并不是bNum,原来是只把低八位赋值了,但并没有将高56位清零。继续mov 一个字也一样,有48位没有清空。当用32位给64位赋值的时候,就会发现rax的高32位被清零了。

因此可以得出以下关键结论:

  1. 用8,16位数字给64位寄存器赋值,不会清空高位
  2. 用32位数字给64会寄存器赋值,会自动清空高位

sasm

接下来安装一个汇编的IDE,sudo apt install nsam: 接下来建一个工程:

image.png

代码如下:

代码语言:javascript复制
%include "io.inc"

extern printf

section .data
number1 dq 42
number2 dq 41

fmt1 db "NUMBER1 >= NUMBER2",10,0
fmt2 db "NUMBER1 < NUMBER2",10,0

section .bss

section .text
global CMAIN
CMAIN:
    push rbp
    mov rbp, rsp; for correct debugging
    ;write your code here
    mov rax, [number1]
    mov rbx, [number2]
    cmp rax, rbx
    jge greater

    mov rdi,fmt2
    mov rax,0
    call printf
    jmp exit
    
greater:
    mov rdi, fmt1
    mov rax,0
    call printf
exit:
    mov rsp, rbp
    pop rbp
    ret

jmp指令结果会体现在eflags上,比如ZF(zero flag),SF(sign flag),OF(overflow flag)等位。具体区别如下:

image.png

再来一段循环代码:

代码语言:javascript复制
%include "io.inc"

extern printf

section .data
number dq 5
fmt db "The sum from 0 to %ld is %ld", 10,0

section .bss

section .text
global CMAIN
CMAIN:
    push rbp
    mov rbp, rsp; for correct debugging
    ;write your code here
    mov rcx, [number]
    mov rax, 0
bloop:
    add rax, rcx
    loop bloop    
    mov rdi, fmt
    mov rsi, [number]
    mov rdx, rax
    mov rax,0
    call printf
exit:
    mov rsp, rbp
    pop rbp
    ret

这儿引入了loop指令,每次循环都会将rcx 减1。这时候我们就完成了ddd和sasm的初步学习。

0 人点赞