//----------------------------------------------------------------- // byteswap.s (Regarding Question IV on Midterm Exam II) // // This program is written to demonstrate that our sequence // of rotation-instructions does indeed succeed in swapping // the order of the 4 bytes in the doubleword register EAX. // // to assemble: $ as byteswap.s -o byteswap.o // and to link: $ ld byteswap.o -o byteswap // and execute: $ ./byteswap // // programmer: ALLAN CRUSE // written on: 10 APR 2009 //----------------------------------------------------------------- .equ dev_STDOUT, 1 .equ sys_WRITE, 1 .equ sys_EXIT, 60 .section .data val: .quad 0x12345678 msg: .ascii "RAX=" buf: .ascii "xxxxxxxxxxxxxxxx \n" len: .quad . - msg hex: .ascii "0123456789ABCDEF" .section .text _start: #------------------------------ # show the original byte-order #------------------------------ mov val, %eax lea buf, %rdi call rax2hex mov $sys_WRITE, %rax mov $dev_STDOUT, %rdi lea msg, %rsi mov len, %rdx syscall #----------------------------------------------- # apply our sequence of byte-swapping rotations #----------------------------------------------- mov val, %eax # fetch the 4-byte value in memory rol $8, %ax # swap the two bytes in AX rol $16, %eax # swap the two words in EAX rol $8, %ax # swap the two bytes in AX mov %eax, val # store the 4-byte value to memory #------------------------------ # show the modified byte-order #------------------------------ mov val, %eax lea buf, %rdi call rax2hex mov $sys_WRITE, %rax mov $dev_STDOUT, %rdi lea msg, %rsi mov len, %rdx syscall #----------------------------- # terminate this demo-program #----------------------------- mov $sys_EXIT, %rax xor %rdi, %rdi syscall # this subroutine formats the value found in register RAX as a # string of hexadecimal numerals at the address found in RDI. rax2hex: push %rax push %rbx push %rcx push %rdx push %rdi mov $16, %rcx nxnyb: rol $4, %rax mov %al, %bl and $0xF, %rbx mov hex(%rbx), %dl mov %dl, (%rdi) inc %rdi loop nxnyb pop %rdi pop %rdx pop %rcx pop %rbx pop %rax ret .global _start .end