- #----------------------------------------------------------------
- # Program lab_3.s - Architektury Komputerów
- #----------------------------------------------------------------
- #
- # To compile: as --defsym FUNC_V1=1 -o lab_3.o lab_3.s
- # To link: ld -o lab_3 lab_3.o
- # To run: ./lab_3
- #
- #----------------------------------------------------------------
- .equ write_64, 0x01 # write data to file function
- .equ exit_64, 0x3C # exit program function
- .equ stdout, 0x01 # handle to stdout
- .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)
- #----------------------------------------------------------------
- .text
- .global _start
- .macro disp_str_64 file_id, address, length
- mov $write_64, %rax
- mov \file_id, %rdi
- mov \address, %rsi
- mov \length, %rdx
- syscall
- .endm
- .macro exit_prog_64 exit_code
- mov $exit_64, %rax
- mov \exit_code, %rdi
- syscall
- .endm
- #----------------------------------------------------------------
- _start:
- mov $256, %r15 # loop counter = 256;
- xor %r14, %r14 # number = 0;
- again:
- mov %r14b, %al
- call byte2hex # ax = hex_code( al );
- movw %ax, hex_str
- disp_str_64 $stdout, $hex_str, $3
- inc %r14 # number++;
- mov %r14, %rax # if( !(number % 16) ) newline();
- and $15, %rax
- jnz skip
- disp_str_64 $stdout, $new_line, $1
- skip:
- dec %r15 # counter--;
- jnz again
- disp_str_64 $stdout, $new_line, $1
- movb varb, %al # convert byte to hex string
- movb $1, %cl # it's byte, so size = 1
- mov $big_hex_str+2, %rdi # address of most significant digit of least significant byte
- 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 $0 # exit program
- #----------------------------------------------------------------
- # num2hex - converts number to hexadecimal string
- # Arguments: %rax - number (%al, %ax, %eax)
- # %cl - size of number (1,2,4,8)
- # %rdi - address (where to put hex digits)
- #----------------------------------------------------------------
- .type num2hex, @function
- num2hex:
- mov %rax, %rdx # store original value in %rdx
- next_byte:
- call byte2hex # convert byte in %al to two hexdigits (in %ax)
- movw %ax, (%rdi) # store digits in memory (string)
- sub $2, %rdi # move two chars to the left
- 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
- #----------------------------------------------------------------
- # byte2hex - converts byte to hexadecimal number (first version)
- # Argument: %al - byte to convert
- # Returns: %ax - two hex digits
- #----------------------------------------------------------------
- .ifdef FUNC_V1
- .type byte2hex,@function
- byte2hex:
- MOVB %al, tmp
- ANDB $0x0F,%al # first nibble
- CMPB $10,%al
- JB digit1
- ADDB $('A'-10),%al
- JMP insert1
- digit1:
- ADDB $'0',%al
- insert1:
- MOVB %al,%ah
- MOVB tmp,%al # second nibble
- SHR $4,%al
- CMPB $10,%al
- JB digit2
- ADDB $('A'-10),%al
- JMP insert2
- digit2:
- ADDB $'0',%al
- insert2:
- RET
- .endif
- #----------------------------------------------------------------
- # byte2hex - converts byte to hexadecimal number (second version)
- # Argument: %al - byte to convert
- # Returns: %ax - two hex digits
- #----------------------------------------------------------------
- .ifdef FUNC_V2
- .type byte2hex,@function
- byte2hex:
- MOVB %al, tmp
- ANDB $0x0F, %al # first nibble
- MOVZX %al, %rbx # rbx = al; zeros in empty space
- MOVB hex_digit(%rbx), %ah # ah = hex_digit[ rbx ]
- 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
- #----------------------------------------------------------------
- # byte2hex - converts byte to hexadecimal number (third version)
- # Argument: %al - byte to convert
- # Returns: %ax - two hex digits
- #----------------------------------------------------------------
- .ifdef FUNC_V3
- .type byte2hex,@function
- byte2hex:
- MOVZX %al, %rbx # rbx = al; zeros in empty space
- MOVW hex_digits(,%rbx,2), %ax # ah = hex_digit[ rbx ]
- RET
- .endif