# Program
#----------------------------------------------------------------
#
# To compile: as
# To
# To
#
#----------------------------------------------------------------
.equ write_64, 1
.equ exit_64, 60
.equ stdout, 1
#----------------------------------------------------------------
vector: #
.long 10,70,50,90,60,80,40,20,0,30,98,78
count: # count of items
.quad ( . - vector ) >> 2
item:
.string "Item "
line_no:
.string " "
itemval:
.string " = "
number:
.string " \n"
FL_text:
.string "\nFrom first to
.equ exit_64, 0x3C # exit program function
.equ stdout, 0x01 # handle
LF_text:
.string "\nFrom last to
.data
hex_str:
.ascii "00 " # hex code string
big_hex_str:
.ascii "0x0000000000000000" # big hex code string
new_line:
.ascii "\n" # new line
tmp:
.byte 0 # tmp variable
.ifdef FUNC_V2
hex_digit:
.byte '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
.endif
.ifdef FUNC_V3
hex_digits:
.ascii "00","01","02","03","04","05","06","07"
.ascii "08","09","0A","0B","0C","0D","0E","0F"
.ascii "10","11","12","13","14","15","16","17"
.ascii "18","19","1A","1B","1C","1D","1E","1F"
.ascii "20","21","22","23","24","25","26","27"
.ascii "28","29","2A","2B","2C","2D","2E","2F"
.ascii "30","31","32","33","34","35","36","37"
.ascii "38","39","3A","3B","3C","3D","3E","3F"
.ascii "40","41","42","43","44","45","46","47"
.ascii "48","49","4A","4B","4C","4D","4E","4F"
.ascii "50","51","52","53","54","55","56","57"
.ascii "58","59","5A","5B","5C","5D","5E","5F"
.ascii "60","61","62","63","64","65","66","67"
.ascii "68","69","6A","6B","6C","6D","6E","6F"
.ascii "70","71","72","73","74","75","76","77"
.ascii "78","79","7A","7B","7C","7D","7E","7F"
.ascii "80","81","82","83","84","85","86","87"
.ascii "88","89","8A","8B","8C","8D","8E","8F"
.ascii "90","91","92","93","94","95","96","97"
.ascii "98","99","9A","9B","9C","9D","9E","9F"
.ascii "A0","A1","A2","A3","A4","A5","A6","A7"
.ascii "A8","A9","AA","AB","AC","AD","AE","AF"
.ascii "B0","B1","B2","B3","B4","B5","B6","B7"
.ascii "B8","B9","BA","BB","BC","BD","BE","BF"
.ascii "C0","C1","C2","C3","C4","C5","C6","C7"
.ascii "C8","C9","CA","CB","CC","CD","CE","CF"
.ascii "D0","D1","D2","D3","D4","D5","D6","D7"
.ascii "D8","D9","DA","DB","DC","DD","DE","DF"
.ascii "E0","E1","E2","E3","E4","E5","E6","E7"
.ascii "E8","E9","EA","EB","EC","ED","EE","EF"
.ascii "F0","F1","F2","F3","F4","F5","F6","F7"
.ascii "F8","F9","FA","FB","FC","FD","FE","FF"
.endif
varb: .byte 190 # byte value (2 chars)
varw: .word 51966 # word value (4 chars)
varl: .long 3735927486 # long value (8 chars)
varq: .quad 18369548392556473261 # quad value (16 chars)
dataend:
.equ item_len, FL_text - item
.equ FL_len, LF_text - FL_text
.equ LF_len, dataend - LF_text
#----------------------------------------------------------------
mov \file_id,
mov \address,
mov \length,
syscall
.
syscall
.endm
mov \exit_code,
syscall
.
syscall
.endm
#----------------------------------------------------------------
_start:
inc %r14
mov %r14, %rax
CALL disp_vector_FL #
and $15, %rax
jnz skip
disp_str_64 $stdout,
skip:
dec %r15
jnz again
disp_str_64 $stdout, $new_line, $1
movb varb, %al
CALL disp_vector_LF #
movb $1, %cl # it's byte, so size = 1
mov $big_hex_str+2, %rdi # address
call num2hex
disp_str_64 $stdout, $big_hex_str, $4 # 0x + 2 digits
disp_str_64 $stdout, $new_line, $1
movw varw, %ax # convert word to hex string
movb $2, %cl # it's word, so size = 2
mov $big_hex_str+4, %rdi # address of most significant digit of least significant byte
call num2hex
disp_str_64 $stdout, $big_hex_str, $6 # 0x + 4 digits
disp_str_64 $stdout, $new_line, $1
movl varl, %eax # convert long to hex string
movb $4, %cl # it's long, so size = 4
mov $big_hex_str+8, %rdi # address of most significant digit of least significant byte
call num2hex
disp_str_64 $stdout, $big_hex_str, $10 # 0x + 8 digits
disp_str_64 $stdout, $new_line, $1
movq varq, %rax # convert quad to hex string
movb $8, %cl # it's quad, so size = 8
mov $big_hex_str+16, %rdi # address of most significant digit of least significant byte
call num2hex
disp_str_64 $stdout, $big_hex_str, $18 # 0x + 16 digits
disp_str_64 $stdout, $new_line, $1
theend:
exit_prog_64
#----------------------------------------------------------------
# Arguments: %rax - number (%al, %ax, %eax)
# %cl - size of number (1,2,4,8)
# %rdi - address (where to put hex digits)
#----------------------------------------------------------------
.
# Function: disp_vector_FL
# Parameters: none
#
.type
num2hex:
mov %rax, %rdx
disp_vector_FL:
MOV count,%rcx #
next_byte:
call byte2hex
XOR %rsi,%rsi # data index
next_item:
MOV vector(,%rsi,4),%ebx # get data
CALL make_string # convert
movw %ax, (%rdi)
push %rcx
push %rsi
disp_str_64 $stdout, $item, $item_len #
sub $2, %rdi
pop %rsi
pop %rcx
INC %rsi #
LOOP next_item # { rcx--; if( rcx ) goto next_item }
RET # return to
shr $8, %rdx # shift original value right
mov %rdx, %rax # copy value to %rax
dec %cl # size--;
jnz next_byte # more bytes to convert
ret
#----------------------------------------------------------------
# Argument: %al - byte to convert
# Returns: %ax - two hex digits
#----------------------------------------------------------------
.ifdef FUNC_V1
.
# Function: disp_vector_LF
# Parameters: none
#
.type
byte2hex:
MOVB %al, tmp
ANDB $0x0F,%al
disp_vector_LF:
MOV count,%rcx #
CMPB $10,%al
JB digit1
ADDB $('A'-10),%al
JMP insert1
digit1:
ADDB $'0',%al
insert1:
MOVB %al,%ah
MOVB tmp,%al
MOV %rcx,%rsi #
SHR $4,%al
CMPB $10,%al
JB digit2
ADDB $('A'-10),%al
JMP insert2
digit2:
ADDB $'0',%al
insert2:
RET
.endif
DEC %rsi # data index--
prev_item:
MOV vector(,%rsi,4),%ebx # get data
CALL make_string # convert to string
push %rcx
push %rsi
disp_str_64 $stdout, $item, $item_len # display prepared string
pop %rsi
pop %rcx
DEC %rsi # previous element
LOOP prev_item # { rcx--; if( rcx ) goto prev_item }
RET # return to main program
#----------------------------------------------------------------
# Function: make_string
# Parameters: %esi -
# Argument: %al
# %ebx -
# Returns: %ax - two hex digits
#----------------------------------------------------------------
.ifdef FUNC_V2
.
#
.type
byte2hex:
MOVB %al, tmp
ANDB $0x0F, %al
make_string:
# MOVL $0x20202020, number
MOVW $0x2020, line_no
MOV %esi,%eax #
MOVZX %al, %rbx
MOV $line_no + 2,%rdi
CALL num2dec
MOV %ebx,%eax #
MOVB hex_digit(%rbx), %ah
MOV $number + 4,%rdi
CALL num2dec
RET #
MOVB tmp, %al # second nibble
SHR $4, %al
MOVZX %al, %rbx # rbx = al; zeros in empty space
MOVB hex_digit(%rbx), %al # al = hex_digit[ rbx ]
RET
.endif
#----------------------------------------------------------------
# Function: num2dec
# Parameters: %eax -
# Argument: %al
# %rdi -
# Returns: %ax - two hex digits
#----------------------------------------------------------------
.ifdef FUNC_V3
.
#
.type
byte2hex:
MOVZX %al, %rbx
num2dec:
PUSH %rbx #
PUSH %rdx # save register on stack
MOV $10,%ebx # divisor in
MOVW hex_digits(,%rbx,2), %ax
nextdig:
XOR %edx,%edx #
RET
.endif
DIV %ebx # EDX:EAX div EBX
ADD $'0',%dl # convert remainder (in EDX) to character
MOV %dl,(%rdi) # *(RDI) = character (decimal digit)
CMP $0,%eax # quotient in EAX
JZ empty
DEC %rdi # RDI--
JMP nextdig
empty:
POP %rdx # restore register from stack
POP %rbx # restore register from stack
RET # return to make_string function
#----------------------------------------------------------------