TILE IA-64 E2K absd128 9 5 4 binsrch 15 9 11 bitr128 2 8 6 gcdivis 12 10 8 getipstr 11 8 9 getmacst 17 10 16 getvlq 4 5 6 heapSort 32 22 30 inssort 14 9 10 lcmult 6 7 4 nsamebit 3 3 6 putipstr 21 21 16 putmacst 13 8 10 putvlq 9 7 9 sequence 7 7 7 sqrt128 11 7 11 srch128 11 6 11 ucnvrf 20 17 12 udiv128 15 9 9 udiv256 22 16 17 umul128 31 20 10 ------------------------- 285 214 222 S/390x AMD64 ARM64 ARC64 PPC64 SPARC64 MIPS64 RV64 LA64 Alpha MMIX PA2.0 TILE-Gx IA-64 E2K absd128 13 9 6 7 11 12 12 12 12 17 20 6 15 13 14 binsrch 20 15 15 15 19 21 18 18 17 18 19 14 20 16 20 bitr128 14 8 4 9 13 15 13 13 4 16 14 8 4 15 16 gcdivis 16 11 14 10 15 16 12 13 13 14 13 13 14 16 16 getipstr 13 14 12 11 13 14 14 15 15 13 14 11 14 14 16 getmacst 20 24 21 19 25 26 23 24 23 23 23 21 23 19 24 getvlq 14 10 10 10 12 12 9 11 10 11 11 8 9 11 12 heapSort 48 36 34 34 44 48 44 43 38 43 43 35 42 42 50 inssort 17 15 15 14 17 20 16 16 15 17 17 15 17 16 19 lcmult 7 5 5 5 6 5 6 5 5 11 9 9 9 17 9 nsamebit 5 6 9 8 8 6 9 10 9 6 5 9 5 7 12 putipstr 25 26 23 19 26 28 26 24 26 34 28 30 31 35 27 putmacst 16 17 16 14 17 20 18 19 18 18 19 14 16 18 19 putvlq 18 13 12 12 15 18 15 16 15 16 16 13 14 14 16 sequence 9 7 7 7 10 12 11 10 10 10 10 11 9 14 13 sqrt128 12 9 9 11 11 16 15 16 15 18 22 9 17 17 19 srch128 12 11 11 9 14 16 12 13 12 14 16 10 16 13 16 ucnvrf 21 17 16 13 25 24 20 18 18 23 20 21 24 28 21 udiv128 5 5 12 11 16 22 20 19 19 21 9 14 21 22 22 udiv256 25 24 19 18 24 39 31 31 31 38 40 19 32 32 37 umul128 21 13 15 15 15 62 25 21 21 21 25 66 49 33 23 -------------------------------------------------------------------------------------------------- 351 295 285 271 356 452 369 367 346 402 393 356 401 412 421 S/390x AMD64 ARM64 ARC64 PPC64 SPARC64 MIPS64 RV64 LA64 Alpha MMIX PA2.0 TILE-Gx IA-64 E2K absd128 64 24 24 26 44 48 80 48 48 80 80 24 72 80 96 binsrch 96 42 60 52 76 84 96 76 68 80 76 56 120 144 160 bitr128 76 22 16 30 52 64 64 52 16 64 56 32 16 128 144 gcdivis 60 27 56 34 60 64 76 52 52 68 52 52 96 160 136 getipstr 48 27 48 38 52 56 64 60 60 64 56 44 88 128 136 getmacst 84 51 84 66 100 104 112 96 92 96 92 84 136 160 224 getvlq 56 27 40 32 48 48 48 44 40 48 44 32 32 80 88 heapSort 240 115 136 118 176 192 224 172 152 176 172 140 256 352 424 inssort 76 44 60 44 68 80 96 64 60 80 68 60 112 144 216 lcmult 26 15 20 16 24 20 36 20 20 44 36 36 48 112 72 nsamebit 20 18 36 24 32 24 48 40 36 32 20 36 24 48 88 putipstr 104 55 96 86 104 116 144 100 104 144 112 124 168 328 256 putmacst 68 41 68 54 68 80 96 76 72 80 76 56 104 128 152 putvlq 68 37 48 40 60 72 80 64 60 64 64 52 72 112 144 sequence 36 21 28 22 40 48 64 44 40 48 40 44 56 112 96 sqrt128 56 32 36 38 44 64 80 64 60 80 88 36 88 112 176 srch128 60 33 44 32 56 64 64 52 48 64 64 40 88 96 152 ucnvrf 96 54 70 60 108 142 160 84 82 160 85 170 162 266 177 udiv128 24 12 48 40 64 88 96 76 76 96 28 56 120 144 168 udiv256 112 67 76 68 96 156 160 124 124 160 160 76 176 256 288 umul128 88 47 60 58 60 248 112 84 84 96 100 264 248 320 184 -------------------------------------------------------------------------------------------------- 1558 811 1154 978 1432 1862 2000 1492 1394 1824 1569 1514 2282 3410 3577 S/390x LISTING hello.s page 1 1 .global _start,main 2 _start: # Входна точка 3 main: # Точка на прекъсване на gdb 4 0000 41200001 LA 2,1 # Файлов дескриптор 1: stdout (стандартен изход) 5 0004 C0300000 0000 LARL 3,MSG # Адрес на низа 6 000a 4140001B LA 4,LEN # Дължина на низа (UTF-8) 7 000e 0A04 SVC 4 # SYS_write (запис: /usr/include/{архит.}/asm/unistd.h 8 0010 0A01 SVC 1 # SYS_exit (завършване на процеса) 9 0012 0707 .data 10 0000 D097D0B4 D180D0B0 MSG: .ascii "Здравей, свят!\n\n" 10 D0B2D0B5 D0B92C20 10 D181D0B2 D18FD182 10 210A0A 11 001b 00 LEN = . - MSG AMD64 GAS hello.s page 1 1 .intel_syntax noprefix 2 .global _start,main 3 _start: # Входна точка 4 main: # Точка на прекъсване на gdb 5 0000 48C7C001 000000 MOV RAX,1 # SYS_write (запис: /usr/include/{архит.}/asm/unistd.h) 6 0007 48C7C701 000000 MOV RDI,1 # Файлов дескриптор 1: stdout (стандартен изход) 7 000e 488D3425 00000000 LEA RSI,MSG # Адрес на низа 8 0016 48C7C21B 000000 MOV RDX,OFFSET LEN # Дължина на низа (UTF-8) 9 001d 0F05 SYSCALL # Извикай съответната функция на ядрото на ОС 10 001f 48C7C03C 000000 MOV RAX,60 # SYS_exit (завършване на процеса) 11 0026 0F05 SYSCALL 12 .data 13 0000 D097D0B4 D180D0B0 MSG: .ascii "Здравей, свят!\n\n" 13 D0B2D0B5 D0B92C20 13 D181D0B2 D18FD182 13 210A0A 14 LEN = . - MSG AARCH64 GAS hello.s page 1 1 .global _start,main 2 _start: // Входна точка 3 main: // Точка на прекъсване на gdb 4 0000 080880D2 MOV X8,#64 // SYS_write (запис: /usr/include/asm-generic/unistd.h) 5 0004 200080D2 MOV X0,#1 // Файлов дескриптор 1: stdout (стандартен изход) 6 0008 01000010 ADR X1,MSG // Адрес на низа 7 000c 620380D2 MOV X2,#LEN // Дължина на низа (UTF-8) 8 0010 010000D4 SVC 0 // Извикай съответната функция на ядрото на ОС 9 0014 A80B80D2 MOV X8,#93 // SYS_exit (завършване на процеса) 10 0018 010000D4 SVC 0 11 .data 12 0000 D097D0B4 MSG: .ascii "Здравей, свят!\n\n" 12 D180D0B0 12 D0B2D0B5 12 D0B92C20 12 D181D0B2 13 LEN = . - MSG ARC GAS hello.s page 1 1 .global __start,main 2 __start: # Входна точка 3 main: # Точка на прекъсване на gdb 4 0000 8A58 0110 MOVL r8,64 # SYS_write (запис: /usr/include/{архит.}/asm/unistd.h 5 0004 4A58 4000 MOVL r0,1 # Файлов дескриптор 1: stdout (стандартен изход) 6 0008 0A59 800F 0000 0000 MOVL r1,MSG # Адрес на низа 7 0010 0A5A 800F 0000 1B00 MOVL r2,LEN # Дължина на низа (UTF-8) 8 0018 1E78 TRAP_S 0 # Извикай съответната функция на ядрото на ОС 9 001a 8A58 4117 MOVL r8,93 # SYS_exit (завършване на процеса) 10 001e 1E78 TRAP_S 0 11 .data 12 0000 D097 D0B4 D180 D0B0 MSG: .ascii "Здравей, свят!\n\n" 12 D0B2 D0B5 D0B9 2C20 12 D181 D0B2 D18F D182 12 210A 0A 13 LEN = . - MSG PPC LISTING hello.s page 1 1 .global _start,._start,main 2 .section ".opd","aw" # PPC64 ELF ABI изисква дескриптор на функция 3 .align 3 4 _start: # Входна точка 5 0000 00000000 .quad ._start,.TOC.@tocbase,0 5 00000000 5 00000000 5 00000000 5 00000000 6 .previous 7 ._start: 8 main: # Точка на прекъсване на gdb 9 0000 38000004 li r0,4 # SYS_write (запис: /usr/include/sys/syscall.h) 10 0004 38600001 li r3,1 # Файлов дескриптор 1: stdout (стандартен изход 11 0008 3C800000 lis r4,MSG@highest # Зареди битове 48-63 на MSG в битове 16-31 12 000c 60840000 ori r4,r4,MSG@higher# " " " 32-47 " " " " 0-15 13 0010 788407C6 rldicr r4,r4,32,31 # r4 <<= 32 (бит 31 при IBM е всъщност бит 32!) 14 0014 64840000 oris r4,r4,MSG@h # Зареди битове 16-31 на MSG в битове 16-31 15 0018 60840000 ori r4,r4,MSG@l # " " " 0-15 " " " " 0-15 16 001c 38A0001B li r5,LEN # Дължина на низа (UTF-8) 17 0020 44000002 sc # Извикай съответната функция на ядрото на ОС 18 0024 60000000 nop # Ще бъде прескочена при успешен SC (SysCall) 19 0028 38000001 li r0,1 # SYS_exit (завършване на процеса) 20 002c 44000002 sc 21 .data 22 0000 D097D0B4 MSG: .ascii "Здравей, свят!\n\n" 22 D180D0B0 22 D0B2D0B5 22 D0B92C20 22 D181D0B2 23 LEN = . - MSG SPARC GAS hello.s page 1 1 .global _start,main 2 _start: ! Входна точка 3 main: ! Точка на прекъсване на gdb 4 0000 90102001 mov 1,%o0 ! Файлов дескриптор 1: stdout (стандартен изход) 5 0004 15000000 13000000 9412A000 92126000 952AB020 9212400A setx MSG,%o2,%o1! Адрес на низа 6 001c 9410201B mov LEN,%o2 ! Дължина на низа (UTF-8) 7 0020 82102004 mov 4,%g1 ! SYS_write (запис: /usr/include/sys/syscall.h) 8 0024 91D02010 ta 16 ! Извикай съответната функция на ядрото на ОС 9 0028 82102001 mov 1,%g1 ! SYS_exit (завършване на процеса) 10 002c 91D02010 ta 16 11 .align 4 12 .data 13 0000 D097D0B4 D180D0B0 D0B2D0B5 D0B92C20 D181D0B2 D18FD182 MSG: .ascii "Здравей, свят!\n\n" 13 210A0A 14 LEN = . - MSG MIPS LISTING hello.s page 1 1 .ent main 2 .global __start,main 3 __start: # Входна точка 4 main: # Точка на прекъсване на gdb 5 0000 24040001 LI $4,1 # Файлов дескриптор 1: stdout (стандартен изход) 6 0004 3C050000 3C010000 64A50000 64210000 0005283C 00A1282D DLA $5,MSG # Адрес на низа 7 001c 2406001B LI $6,LEN # Дължина на низа (UTF-8) 8 0020 24021389 LI $2,5001 # SYS_write (запис: /usr/include/{архит.}/asm/unistd.h) 9 0024 0000000C SYSCALL # Извикай съответната функция на ядрото на ОС 10 0028 240213C2 LI $2,5058 # SYS_exit (завършване на процеса) 11 002c 0000000C SYSCALL 12 .end main 13 .data 14 0000 D097D0B4 D180D0B0 D0B2D0B5 D0B92C20 D181D0B2 D18FD182 MSG: .ascii "Здравей, свят!\n\n" 14 210A0A 15 001b 00000000 00 LEN = . - MSG RISC-V LISTING hello.s page 1 1 .global _start,main 2 _start: # Входна точка 3 main: # Точка на прекъсване на gdb 4 0000 13051000 LI a0,1 # Файлов дескриптор 1: stdout (стандартен изход) 5 0004 97050000 93850500 LA a1,MSG # Адрес на низа 6 000c 1306B001 LI a2,27 # Дължина на низа (UTF-8) 7 0010 93080004 LI a7,64 # SYS_write (запис: /usr/include/{архит.}/asm/unistd.h) 8 0014 73000000 ECALL # Извикай съответната функция на ядрото на ОС 9 0018 9308D005 LI a7,93 # SYS_exit (завършване на процеса) 10 001c 73000000 ECALL 11 0020 D097D0B4 D180D0B0 D0B2D0B5 MSG: .ascii "Здравей, свят!\n\n" 11 D0B92C20 D181D0B2 D18FD182 11 210A0A00 LOONGARCH64 GAS hello.s page 1 1 .global _start,main 2 _start: # Входна точка 3 main: # Точка на прекъсване на gdb 4 0000 04048003 ORI $r4,$r0,1 # Файлов дескриптор 1: stdout (стандартен изход) 5 0004 0500001A A500C028 LA $r5,MSG # Адрес на низа 6 000c 066C8003 ORI $r6,$r0,27 # Дължина на низа (UTF-8) 7 0010 0B008103 ORI $r11,$r0,64#SYS_write (запис:/usr/include/{архит.}/asm/unistd.h 8 0014 00002B00 SYSCALL 0 # Извикай съответната функция на ядрото на ОС 9 0018 0B748103 ORI $r11,$r0,93# SYS_exit (завършване на процеса) 10 001c 00002B00 SYSCALL 0 11 .data 12 0000 D097D0B4 D180D0B0 MSG: .ascii "Здравей, свят!\n\n" 12 D0B2D0B5 D0B92C20 12 D181D0B2 D18FD182 12 210A0A hello.o: file format ecoff-littlealpha Disassembly of section .text: .globl main .ent main 0000000000000000
: main: # Входна точка и точка на прекъсване на gdb 0: 01 00 bb 27 ldah gp,1(t12) ldah $29,0($27)!gpdisp!1 # pv ($27) не е валиден => и gp ($29) не е, 4: 60 80 bd 23 lda gp,-32672(gp) lda $29,0($29)!gpdisp!1 # но без този пролог b main (gdb) не работи 8: 00 00 60 c3 br t12,c br $27,l1 # Върни програмния брояч pc в pv (procedure value) c: 01 00 bb 27 ldah gp,1(t12) l1: ldgp $29,0($27) # as разширява този макрос като ldah/lda по-горе 10: 54 80 bd 23 lda gp,-32684(gp) 14: ff ff 3d 26 ldah a1,-1(gp) ldah $17,MSG($29)!gprelhigh!2 # Ст.16 б. на 32-б. знаково отм. от gp 18: 10 34 e0 43 addq zero,0x1,a0 lda $17,MSG($17)!gprellow!2 # Младши 16 бита на горното отместване 1c: f0 7f 31 22 lda a1,32752(a1) ldil $16,1 # Файлов дескриптор 1: stdout (стандартен изход) 20: 12 74 e3 43 addq zero,0x1b,a2 ldil $18,27 # Дължина на низа (UTF-8) 24: 00 94 e0 43 addq zero,0x4,v0 ldil $0,4 # SYS_write (запис: /usr/include/sys/syscall.h) 28: 83 00 00 00 callsys call_pal 0x83 # Извикай съответната функция на ядрото на ОС 2c: 00 34 e0 43 addq zero,0x1,v0 ldil $0,1 # SYS_exit (завършване на процеса) 30: 83 00 00 00 callsys call_pal 0x83 34: 1f 04 ff 47 nop .end main 38: 00 00 fe 2f unop .data 3c: 1f 04 ff 47 nop MSG: .ascii "Здравей, свят!\n\n" GAS for MMIX hello.s page 1 1 % Вж http://mmix.cs.hm.edu/examples/hello.html 2 3 loc 0x100 4 0000 23FF0000 LDA $255,MSG % Адрес на низа 5 0004 00000701 TRAP 0,7,1 % 7 = Fputs, 1 = StdOut 6 0008 00000000 TRAP 0,0,0 % 0 = Halt (функции на симулатора mmix) 7 8 GREG @ 9 000c D097D0B4 MSG: .ascii "Здравей, свят!\n\n\0" 9 D180D0B0 9 D0B2D0B5 9 D0B92C20 9 D181D0B2 9 D18FD182 HPPA64 LISTING hello.s page 1 1 .global _start,main 2 _start: ; Входна точка 3 main: ; Точка на прекъсване на gdb 4 0000 B7F90032 ADDI MSG-_start-3,%R31,%R25; Адрес на низа 5 0004 341A0002 LDI 1,%R26 ; Файлов дескриптор 1: stdout (стандартен изход 6 0008 34140008 LDI 4,%R20 ; SYS_write (/usr/include/{архит.}/asm/unistd.h 7 000c E4008200 BE,L 0x100(%SR2,%R0),%SR0,%R31; Извикай функцията на ядрото отложено 8 0010 34180036 LDI LEN,%R24 ; Дължина на низа (изпълнява се преди „BE,L“!) 9 0014 E4008200 BE,L 0x100(%SR2,%R0),%SR0,%R31 10 0018 34140002 LDI 1,%R20 ; SYS_exit (завършване; изпълн.се преди „BE,L“) 11 12 001c D097D0B4 MSG: .ascii "Здравей, свят!\n\n" 12 D180D0B0 12 D0B2D0B5 12 D0B92C20 12 D181D0B2 13 LEN = . - MSG TILE-Gx GAS hello.s page 1 1 .global _start,main 2 _start: # Входна точка 3 main: # Точка на прекъсване на gdb 4 { MOVEI r10,64 # SYS_write (запис: /usr/include/{архит.}/asm/unistd.h) 5 0000 CA0F1440 E00F0818 MOVEI r0,1 } # Файлов дескриптор 1: stdout (стандартен изход) 6 0008 003048D1 E0070000 MOVELI r1,hw3_last(MSG) # Битове 63-48 на адреса 7 0010 003048D1 20000038 SHL16INSLI r1,r1,hw2(MSG) # Битове 47-32 на адреса 8 0018 003048D1 20000038 SHL16INSLI r1,r1,hw1(MSG) # Битове 31-16 на адреса 9 { SHL16INSLI r1,r1,hw0(MSG) # Битове 15-00 на адреса 10 0020 41000070 E1DF0818 MOVEI r2,27 } # Дължина на низа (UTF-8) 11 0028 00504851 00186B28 SWINT1 # Извикай съответната функция на ядрото на ОС 12 0030 00304851 E5EF0A18 MOVEI r10,93 # SYS_exit (завършване на процеса) 13 0038 00504851 00186B28 SWINT1 14 .data 15 0000 D097D0B4 D180D0B0 MSG: .ascii "Здравей, свят!\n\n" 15 D0B2D0B5 D0B92C20 15 D181D0B2 D18FD182 15 210A0A IA-64 GAS hello.s page 1 1 .global _start,main 2 _start: // Входна точка 3 main: // Точка на прекъсване на gdb 4 MOV r3=ip // Начален адрес за относителната адресация 5 ADDS r15=4,r0 // SYS_write (запис: /usr/include/{архит.}/unistd.h) 6 ADDS r32=1,r0 //Файлов дескриптор 1: stdout (стандартен изход) 7 0000 00000000 01003000 006000E0 41000084 ADDL r33=(MSG-.),r3// Адрес на низа 8 ADDS r34=LEN,r0 // Дължина на низа (UTF-8) 9 0010 0A000500 00211082 0D004840 B4010084 BREAK 0x100000 // Извикай съответната функция на ядрото на ОС 10 ADDS r15=1,r0 // SYS_exit (завършване на процеса) 11 BREAK 0x100000 12 0020 01000000 0002F008 00004200 00000008 MSG: .ascii "Здравей, свят!\n\n" 12 D097D0B4 D180D0B0 D0B2D0B5 D0B92C20 12 D181D0B2 D18FD182 210A0A 13 LEN = . - MSG E2K GAS hello.s page 1 1 .global _start,main 2 _start: ! Входна точка 3 main: ! Точка на прекъсване на gdb 4 { ord 0,4,%b[0] ! SYS_write (запис:/usr/include/{арх.}/asm/unistd.h 5 ord 0,1,%b[1] ! Файлов дескриптор 1: stdout (стандартен изход) 6 ord 0,[MSG],%b[2]!Адрес на низа 7 ord 0,27,%b[3] ! Дължина на низа (UTF-8) 8 0000 4540003C 00C4C005 01C1C005 02DDC005 03D4C005 03000060 00000000 00000000 00000000 00001B00 sdisp %ctpr1,3 } ! Подготви системното повикване 9 0028 12900000 200400C0 04000050 00000000 call %ctpr1,wbs=4! Извикай съответната функция на ядрото на ОС 10 { ord 0,1,%b[0] ! SYS_exit (завършване на процеса) 11 0038 12400004 00C1C005 03000060 00000000 sdisp %ctpr1,3 } 12 0048 12900000 200400C0 04000050 00000000 call %ctpr1,wbs=4 13 .data 14 0000 D097D0B4 D180D0B0 D0B2D0B5 D0B92C20 D181D0B2 D18FD182 210A0A MSG: .ascii "Здравей, свят!\n\n" S/390x LISTING umul128.s page 1 1 # 128-битовите числа без знак в регистри 5:4 (Y1:Y0) и 3:2 (Z1:Z0) да се 2 # умножат и 256-битовият резултат да се върне в регистри 5:4:3:2 (A:B:C:D). 3 # Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 4 5 .global umul128 6 umul128: 7 0000 EB6DF010 0024 STMG 6,13,16(15) # Съхрани използваните регистри (LNUX-1007-02) 8 0006 B9040072 LGR 7,2 # Z0 9 000a B9040093 LGR 9,3 # Z1 10 000e B90400D4 LGR 13,4 # Y0 11 0012 B90400B5 LGR 11,5 # Y1 12 0016 B9860065 MLGR 6,5 # 6:7 = Z0 * Y1 13 001a B98600C2 MLGR 12,2 # 12:13 = C:D = Z0 * Y0 14 001e B9860084 MLGR 8,4 # 8:9 = Z1 * Y0 15 0022 B98600A3 MLGR 10,3 # 10:11 = Z1 * Y1 16 0026 B9090055 SGR 5,5 17 002a B90A00C7 ALGR 12,7 # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 18 002e B9880068 ALCGR 6,8 # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 19 0032 B98800A5 ALCGR 10,5 # A = ст.д.(Z1 * Y1) 20 0036 B90A00C9 ALGR 12,9 # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 21 003a B988006B ALCGR 6,11 # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 22 003e B988005A ALCGR 5,10 # A 23 0042 B9040046 LGR 4,6 # B 24 0046 B904003C LGR 3,12 # C 25 004a B904002D LGR 2,13 # D 26 004e EB6DF010 0004 LMG 6,13,16(15) # Възстанови съхранените регистри 27 0054 07FE0707 BR 14 # Върни управлението AMD64 GAS umul128.s page 1 1 # 128-битовите числа без знак в регистри RCX:RDX (Y1:Y0) и RSI:RDI (Z1:Z0) да се 2 # умножат и 256-битовият резултат да се върне в рег. RCX:RDX:RSI:RDI (A:B:C:D). 3 # Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 4 5 .intel_syntax noprefix 6 .global umul128 7 umul128: 8 0000 4989FA MOV R10,RDI # Z0 9 0003 C462FBF6 CE MULX R9,RAX,RSI # R9:RAX = Z1 * Y0 10 0008 C462C3F6 C7 MULX R8,RDI,RDI # R8:RDI = Z0 * Y0 11 000d 4889CA MOV RDX,RCX # Y1 12 0010 C4E2A3F6 CE MULX RCX,R11,RSI# RCX:R11 = Z1 * Y1 13 0015 C4C2CBF6 D2 MULX RDX,RSI,R10# RDX:RSI = Z0 * Y1 14 001a 4C01C6 ADD RSI,R8 # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 15 001d 4C11CA ADC RDX,R9 # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 16 0020 4883D100 ADC RCX,0 # A = ст.д.(Z1 * Y1) 17 0024 4801C6 ADD RSI,RAX # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 18 0027 4C11DA ADC RDX,R11 # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 19 002a 4883D100 ADC RCX,0 20 002e C3 RET AARCH64 GAS umul128.s page 1 1 // 128-битовите числа без знак в регистри X3:X2 (Y1:Y0) и X1:X0 (Z1:Z0) да се 2 // умножат и 256-битовият резултат да се върне в рег. X3:X2:X1:X0 (A:B:C:D). 3 // Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 4 5 .global umul128 6 umul128: 7 0000 067CC39B UMULH X6,X0,X3 8 0004 057C039B MUL X5,X0,X3 // X6:X5 = Z0 * Y1 9 0008 447CC09B UMULH X4,X2,X0 10 000c 407C009B MUL X0,X2,X0 // X4:X0 = C:D = Z0 * Y0 11 0010 277C029B MUL X7,X1,X2 12 0014 287CC29B UMULH X8,X1,X2 // X8:X7 = Z1 * Y0 13 0018 297C039B MUL X9,X1,X3 14 001c 237CC39B UMULH X3,X1,X3 // X3:X9 = Z1 * Y1 15 0020 810005AB ADDS X1,X4,X5 // C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 16 0024 C20008BA ADCS X2,X6,X8 // B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 17 0028 63001F9A ADC X3,X3,XZR // A = ст.д.(Z1 * Y1) 18 002c 210007AB ADDS X1,X1,X7// C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 19 0030 420009BA ADCS X2,X2,X9// B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 20 0034 63001F9A ADC X3,X3,XZR 21 0038 C0035FD6 RET ARC GAS umul128.s page 1 1 # 128-битовите числа без знак в регистри r3:r2 (Y1:Y0) и r1:r0 (Z1:Z0) да се 2 # умножат и 256-битовият резултат да се върне в рег. r3:r2:r1:r0 (A:B:C:D). 3 # Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 4 5 .global umul128 6 umul128: 7 0000 3259 C900 MPYMUL r9,r1,r3 8 0004 3059 C800 MPYL r8,r1,r3 # r9:r8 = Z1 * Y1 9 0008 3259 8700 MPYMUL r7,r1,r2 10 000c 3059 8600 MPYL r6,r1,r2 # r7:r6 = Z1 * Y0 11 0010 3258 C500 MPYMUL r5,r0,r3 12 0014 3058 C400 MPYL r4,r0,r3 # r5:r4 = Z0 * Y1 13 0018 3258 8100 MPYMUL r1,r0,r2 14 001c 3058 8000 MPYL r0,r0,r2 # r1:r0 = C:D = Z0 * Y0 15 0020 0059 0181 ADDL.F r1,r1,r4 # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 16 0024 015D C281 ADCL.F r2,r5,r7 # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 17 0028 4159 0310 ADCL r3,r9,0 # A = ст.д.(Z1 * Y1) 18 002c 0059 8181 ADDL.F r1,r1,r6 # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 19 0030 015A 0282 ADCL.F r2,r2,r8 # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 20 0034 415B 0300 ADCL r3,r3,0 21 0038 E07E J_S [blink] # Върни управлението PPC LISTING umul128.s page 1 1 # 128-битовите числа без знак в регистри r6:r5 (Y1:Y0) и r4:r3 (Z1:Z0) да се 2 # умножат и 256-битовият резултат да се върне в рег. r6:r5:r4:r3 (A:B:C:D). 3 # Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 4 5 .global umul128 6 umul128: 7 0000 7D233012 mulhdu r9,r3,r6 8 0004 7D0331D2 mulld r8,r3,r6 # r9:r8 = Z0 * Y1 9 0008 7CE32812 mulhdu r7,r3,r5 10 000c 7C6329D2 mulld r3,r3,r5 # r7:r3 = C:D = Z0 * Y0 11 0010 7D4429D2 mulld r10,r4,r5 12 0014 7D642812 mulhdu r11,r4,r5 # r11:r10 = Z1 * Y0 13 0018 7D8431D2 mulld r12,r4,r6 14 001c 7CC43012 mulhdu r6,r4,r6 # r6:r12 = Z1 * Y1 15 0020 7C874014 addc r4,r7,r8 # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 16 0024 7CA95914 adde r5,r9,r11 # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 17 0028 7CC60194 addze r6,r6 # A = ст.д.(Z1 * Y1) 18 002c 7C845014 addc r4,r4,r10# C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 19 0030 7CA56114 adde r5,r5,r12# B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 20 0034 7CC60194 addze r6,r6 21 0038 4E800020 blr # Върни управлението SPARC GAS umul128.s page 1 1 ! 128-битовите числа без знак в рег. %o3:%o2 (Y1:Y0) и %o1:%o0 (Z1:Z0) да се 2 ! умножат и 256-битовият резултат да се върне в рег. %o3:%o2:%o1:%o0 (A:B:C:D). 3 ! Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 4 ! 5 ! До процесора SPARC T3 (2010 г.) няма команда „umulxhi“, затова я емулираме 6 ! както е показано на http://icodeguru.com/Embedded/Hacker's-Delight/054.htm 7 ! (алгоритъмът е по фиг. 8-2 на книгата на Henry Warren „Hacker's Delight“): 8 ! 9 ! unsigned long long mulhu(unsigned long long u, unsigned long long v) 10 ! { 11 ! unsigned long long u0, u1, v0, v1, w0, w1, w2, t; 12 ! 13 ! u0 = u & 0xFFFFFFFF; 14 ! u1 = u >> 32; 15 ! v0 = v & 0xFFFFFFFF; 16 ! v1 = v >> 32; 17 ! w0 = u0 * v0; 18 ! t = u1 * v0 + (w0 >> 32); 19 ! w1 = t & 0xFFFFFFFF; 20 ! w2 = t >> 32; 21 ! w1 = u0 * v1 + w1; 22 ! return u1 * v1 + w2 + (w1 >> 32); 23 ! } 24 25 ! https://docs.oracle.com/cd/E37838_01/pdf/E61063.pdf, стр. 68 26 0000 9DE3BF50 MULHU: save %sp,-176,%sp ! // u = %i0, v = %i1 27 0004 353FFFFF B416A3FF setx 0xFFFFFFFF,%l0,%i2!//%i2 = 0xFFFFFFFF 28 000c A00E001A and %i0,%i2,%l0 ! u0 = u & 0xFFFFFFFF; 29 0010 A3363020 srlx %i0,32,%l1 ! u1 = u >> 32; 30 0014 A40E401A and %i1,%i2,%l2 ! v0 = v & 0xFFFFFFFF; 31 0018 A7367020 srlx %i1,32,%l3 ! v1 = v >> 32; 32 001c A84C0012 mulx %l0,%l2,%l4 ! w0 = u0 * v0; 33 0020 AE4C4012 mulx %l1,%l2,%l7 ! t = u1 * v0 34 0024 A9353020 srlx %l4,32,%l4 ! w0 >>= 32; 35 0028 AE05C014 add %l7,%l4,%l7 ! t += w0; 36 002c AA0DC01A and %l7,%i2,%l5 ! w1 = t & 0xFFFFFFFF; 37 0030 AD35F020 srlx %l7,32,%l6 ! w2 = t >> 32; 38 0034 A04C0013 mulx %l0,%l3,%l0 ! u0 *= v1; 39 0038 AA054010 add %l5,%l0,%l5 ! w1 += u0; 40 003c A24C4013 mulx %l1,%l3,%l1 ! u1 *= v1; 41 0040 A2044016 add %l1,%l6,%l1 ! u1 += w2; 42 0044 AB357020 srlx %l5,32,%l5 ! w1 >>= 32; 43 0048 B0044015 add %l1,%l5,%i0 ! return u1 + w1; // %i0 44 004c 81CFE008 return %i7+8 !Възстанови прозореца и върни управлението 45 0050 01000000 nop 46 47 .global umul128 48 umul128: 49 0054 9DE3BF50 save %sp,-176,%sp ! След „save“ изходните регистри стават входни! 50 ! umulxhi %i0,%i3,%l2 ! За тази команда се изисква поне „SPARC T3“!!! 51 0058 90100018 mov %i0,%o0 52 005c 7FFFFFE9 call MULHU 53 0060 9210001B mov %i3,%o1 ! Изпълнява се преди „call“! 54 0064 A4100008 mov %o0,%l2 55 0068 A24E001B mulx %i0,%i3,%l1 ! %l2:%l1 = Z0 * Y1 56 ! umulxhi %i0,%i2,%l0 57 006c 90100018 mov %i0,%o0 58 0070 7FFFFFE4 call MULHU 59 0074 9210001A mov %i2,%o1 60 0078 A0100008 mov %o0,%l0 61 007c B04E001A mulx %i0,%i2,%i0 ! %l0:%i0 = C:D = Z0 * Y0 62 0080 A64E401A mulx %i1,%i2,%l3 63 ! umulxhi %i1,%i2,%l4 ! %l4:%l3 = Z1 * Y0 64 0084 90100019 mov %i1,%o0 65 0088 7FFFFFDE call MULHU 66 008c 9210001A mov %i2,%o1 67 0090 A8100008 mov %o0,%l4 68 0094 AA4E401B mulx %i1,%i3,%l5 69 ! umulxhi %i1,%i3,%i3 ! %i3:%l5 = Z1 * Y1 70 0098 90100019 mov %i1,%o0 71 009c 7FFFFFD9 call MULHU 72 00a0 9210001B mov %i3,%o1 73 00a4 B6100008 mov %o0,%i3 74 00a8 B2840011 addcc %l0,%l1,%i1 ! C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 75 ! addxccc %l2,%l4,%i2 ! B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 76 00ac 2A600002 bcs,a,pn %xcc,.+8 !Ако няма пренос, следващата команда се анулира 77 00b0 A404A001 inc %l2! C=0 (FFFFFFFFFFFFFFFF² = FFFFFFFFFFFFFFFE0000000000000001) 78 00b4 B4848014 addcc %l2,%l4,%i2 79 ! addxc %i3,%g0,%i3 ! A = ст.д.(Z1 * Y1) 80 00b8 2A600002 bcs,a,pn %xcc,.+8 81 00bc B606E001 inc %i3 82 00c0 B2864013 addcc %i1,%l3,%i1!C= ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 83 ! addxccc %i2,%l5,%i2!B= ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 84 00c4 1A680008 bcc,pt %xcc,.+32 ! Ако няма пренос, премини към „addcc“ 85 00c8 01000000 nop 86 00cc B486A001 inccc %i2 ! Иначе го добави и ако сега няма пренос, 87 00d0 1A680005 bcc,pt %xcc,.+20 ! също премини към „addcc“ 88 00d4 01000000 nop 89 00d8 B4068015 add %i2,%l5,%i2 ! Иначе изпълни „add“ (която, дори да не даде 90 00dc 0A600003 bcs,pn %xcc,.+12 ! пренос, няма да промени xcc) и отиди на „bcs“ 91 00e0 01000000 nop 92 00e4 B4868015 addcc %i2,%l5,%i2 93 ! addxc %i3,%g0,%i3 ! За „addxc[cc]“ се изисква поне „SPARC T3“!!! 94 00e8 2A600002 bcs,a,pn %xcc,.+8 95 00ec B606E001 inc %i3 96 00f0 81CFE008 return %i7+8 97 00f4 01000000 nop MIPS LISTING umul128.s page 1 1 # 128-битовите числа без знак в регистри $7:$6 (Y1:Y0) и $5:$4 (Z1:Z0) да се 2 # умножат и 256-битовият резултат да се върне в рег. $7:$6:$5:$4 (A:B:C:D). 3 # Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 4 5 .ent umul128 6 .global umul128 7 umul128: 8 0000 0087001D DMULTU $4,$7 9 0004 00005010 MFHI $10 10 0008 00004812 MFLO $9 # $10:$9 = Z0 * Y1 11 000c 0086001D DMULTU $4,$6 12 0010 00004010 MFHI $8 13 0014 00002012 MFLO $4 # $8:$4 = C:D = Z0 * Y0 14 0018 00A6001D DMULTU $5,$6 15 001c 00006010 MFHI $12 16 0020 00005812 MFLO $11 # $12:$11 = Z1 * Y0 17 0024 00A7001D DMULTU $5,$7 18 0028 00003810 MFHI $7 19 002c 00006812 MFLO $13 # $7:$13 = Z1 * Y1 20 0030 0109282D DADDU $5,$8,$9 # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 21 0034 00A8702B SLTU $14,$5,$8 # Получи преноса 22 0038 014C302D DADDU $6,$10,$12 # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 23 003c 00CE302D DADDU $6,$6,$14 # Отчети преноса 24 0040 00CA702B SLTU $14,$6,$10 # Получи преноса 25 0044 00EE382D DADDU $7,$7,$14 # A = ст.д.(Z1 * Y1) 26 0048 00AB282D DADDU $5,$5,$11# C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 27 004c 00AB702B SLTU $14,$5,$11 # Получи преноса 28 0050 00CD302D DADDU $6,$6,$13# B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 29 0054 00CE302D DADDU $6,$6,$14 # Отчети преноса 30 0058 00CD702B SLTU $14,$6,$13 # Получи преноса 31 DADDU $7,$7,$14 # Отчети преноса 32 005c 03E00008 00EE382D JR $31 # Върни управлението 33 0064 00000000 00000000 00000000 .end umul128 RISC-V LISTING umul128.s page 1 1 # 128-битовите числа без знак в регистри a3:a2 (Y1:Y0) и a1:a0 (Z1:Z0) да се 2 # умножат и 256-битовият резултат да се върне в рег. a3:a2:a1:a0 (A:B:C:D). 3 # Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 4 5 .global umul128 6 umul128: 7 0000 B307D502 MUL a5,a0,a3 8 0004 3338D502 MULHU a6,a0,a3 # a6:a5 = Z0 * Y1 9 0008 3337C502 MULHU a4,a0,a2 10 000c 3305C502 MUL a0,a0,a2 # a4:a0 = C:D = Z0 * Y0 11 0010 B3B2C502 MULHU t0,a1,a2 12 0014 B388C502 MUL a7,a1,a2 # t0:a7 = Z1 * Y0 13 0018 3383D502 MUL t1,a1,a3 14 001c B3B6D502 MULHU a3,a1,a3 # a3:t1 = Z1 * Y1 15 0020 B305F700 ADD a1,a4,a5 # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 16 0024 B3B3E500 SLTU t2,a1,a4 # Получи преноса 17 0028 33065800 ADD a2,a6,t0 # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 18 002c 33067600 ADD a2,a2,t2 # Отчети преноса 19 0030 B3330601 SLTU t2,a2,a6 # Получи преноса 20 0034 B3867600 ADD a3,a3,t2 # A = ст.д.(Z1 * Y1) 21 0038 B3851501 ADD a1,a1,a7 # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 22 003c B3B31501 SLTU t2,a1,a7 # Получи преноса 23 0040 33066600 ADD a2,a2,t1 # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 24 0044 33067600 ADD a2,a2,t2 # Отчети преноса 25 0048 B3336600 SLTU t2,a2,t1 # Получи преноса 26 004c B3867600 ADD a3,a3,t2 # Отчети преноса 27 0050 67800000 RET # Върни управлението LOONGARCH64 GAS umul128.s page 1 1 # 128-битовите числа без знак в регистри r7:r6 (Y1:Y0) и r5:r4 (Z1:Z0) да се 2 # умножат и 256-битовият резултат да се върне в рег. r7:r6:r5:r4 (A:B:C:D). 3 # Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 4 5 .global umul128 6 umul128: 7 0000 899C1D00 MUL.D $r9,$r4,$r7 8 0004 8A9C1E00 MULH.DU $r10,$r4,$r7 # r10:r9 = Z0 * Y1 9 0008 88981E00 MULH.DU $r8,$r4,$r6 10 000c 84981D00 MUL.D $r4,$r4,$r6 # r8:r4 = C:D = Z0 * Y0 11 0010 AC981E00 MULH.DU $r12,$r5,$r6 12 0014 AB981D00 MUL.D $r11,$r5,$r6 # r12:r11 = Z1 * Y0 13 0018 AD9C1D00 MUL.D $r13,$r5,$r7 14 001c A79C1E00 MULH.DU $r7,$r5,$r7 # r7:r13 = Z1 * Y1 15 0020 05A51000 ADD.D $r5,$r8,$r9 # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 16 0024 AEA01200 SLTU $r14,$r5,$r8 # Получи преноса 17 0028 46B11000 ADD.D $r6,$r10,$r12 # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 18 002c C6B81000 ADD.D $r6,$r6,$r14 # Отчети преноса 19 0030 CEA81200 SLTU $r14,$r6,$r10 # Получи преноса 20 0034 E7B81000 ADD.D $r7,$r7,$r14 # A = ст.д.(Z1 * Y1) 21 0038 A5AC1000 ADD.D $r5,$r5,$r11#C=ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 22 003c AEAC1200 SLTU $r14,$r5,$r11 # Получи преноса 23 0040 C6B41000 ADD.D $r6,$r6,$r13#B=ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 24 0044 C6B81000 ADD.D $r6,$r6,$r14 # Отчети преноса 25 0048 CEB41200 SLTU $r14,$r6,$r13 # Получи преноса 26 004c E7B81000 ADD.D $r7,$r7,$r14 # Отчети преноса 27 0050 2000004C JIRL $r0,$r1,0 # Върни управлението # 128-битовите числа без знак в рег. $19:$18 (Y1:Y0) и $17:$16 (Z1:Z0) да се #умножат и 256-битовият резултат да се върне в рег. $19:$18:$17:$16 (A:B:C:D). umul128.o: file format ecoff-littlealpha # Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 Disassembly of section .text: .ent umul128 .globl umul128 0000000000000000 : umul128: 0: 00 06 12 4e umulh a0,a2,v0 umulh $16,$19,$2 4: 01 04 13 4e mulq a0,a3,t0 mulq $16,$19,$1 # $2:$1 = Z0 * Y1 8: 02 06 13 4e umulh a0,a3,t1 umulh $16,$18,$0 c: 04 06 32 4e umulh a1,a2,t3 mulq $16,$18,$16 # $0:$16 = C:D = Z0 * Y0 10: 03 04 32 4e mulq a1,a2,t2 mulq $17,$18,$3 14: 05 04 33 4e mulq a1,a3,t4 umulh $17,$18,$4 # $4:$3 = Z1 * Y0 18: 13 06 33 4e umulh a1,a3,a3 mulq $17,$19,$5 1c: 11 04 01 40 addq v0,t0,a1 umulh $17,$19,$19 # $19:$5 = Z1 * Y1 20: a6 03 20 42 cmpult a1,v0,t5 addq $0,$1,$17 # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 24: 11 04 23 42 addq a1,t2,a1 cmpult $17,$0,$6 # Получи преноса 28: 10 04 12 4e mulq a0,a2,a0 addq $2,$4,$18 # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 2c: 12 04 44 40 addq t1,t3,a2 addq $6,$18,$18 # Отчети преноса 30: 12 04 d2 40 addq t5,a2,a2 cmpult $18,$2,$6 # Получи преноса 34: a6 03 42 42 cmpult a2,t1,t5 addq $6,$19,$19 # A = ст.д.(Z1 * Y1) 38: 12 04 45 42 addq a2,t4,a2 addq $17,$3,$17#C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 3c: 13 04 d3 40 addq t5,a3,a3 cmpult $17,$3,$6 # Получи преноса 40: a6 03 23 42 cmpult a1,t2,t5 addq $18,$5,$18#B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 44: 12 04 d2 40 addq t5,a2,a2 addq $6,$18,$18 # Отчети преноса 48: a6 03 45 42 cmpult a2,t4,t5 cmpult $18,$5,$6 # Получи преноса 4c: 13 04 d3 40 addq t5,a3,a3 addq $6,$19,$19 # Отчети преноса 50: 01 80 fa 6b ret zero,(ra),0x1 ret # Върни управлението 54: 1f 04 ff 47 nop .end umul128 58: 00 00 fe 2f unop 5c: 1f 04 ff 47 nop GAS for MMIX umul128.s page 1 1 % 128-битовите числа без знак в рег. $3:$2 (Y1:Y0) и $1:$0 (Z1:Z0) да се 2 % умножат и 256-битовият резултат да се върне в рег. $3:$2:$1:$0 (A:B:C:D). 3 % ВНИМАНИЕ: Адресът на връщане е подаден в регистър $11, а не в обичайния rJ! 4 % Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 5 6 .global umul128 7 umul128: 8 0000 1A050003 MULU $5,$0,$3 9 0004 FE060003 GET $6,rH % $6:$5 = Z0 * Y1 10 0008 1A000002 MULU $0,$0,$2 11 000c FE040003 GET $4,rH % $4:$0 = C:D = Z0 * Y0 12 0010 1A070102 MULU $7,$1,$2 13 0014 FE080003 GET $8,rH % $8:$7 = Z1 * Y0 14 0018 1A090103 MULU $9,$1,$3 15 001c FE030003 GET $3,rH % $3:$9 = Z1 * Y1 16 0020 22010405 ADDU $1,$4,$5 % C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 17 0024 320A0401 CMPU $10,$4,$1 % Ако има пренос, $10 = 1, иначе 0 или −1 18 0028 610A0A00 CSN $10,$10,0 % Превърни −1 в 0 19 002c 22020608 ADDU $2,$6,$8 % B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 20 0030 2202020A ADDU $2,$2,$10 % Отчети преноса 21 0034 320A0802 CMPU $10,$8,$2 % Ако има пренос, $10 = 1, иначе 0 или −1 22 0038 610A0A00 CSN $10,$10,0 % Превърни −1 в 0 23 003c 2203030A ADDU $3,$3,$10 % A = ст.д.(Z1 * Y1) 24 0040 22010107 ADDU $1,$1,$7 % C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 25 0044 320A0701 CMPU $10,$7,$1 % Ако има пренос, $10 = 1, иначе 0 или −1 26 0048 610A0A00 CSN $10,$10,0 % Превърни −1 в 0 27 004c 22020209 ADDU $2,$2,$9 % B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 28 0050 2202020A ADDU $2,$2,$10 % Отчети преноса 29 0054 320A0902 CMPU $10,$9,$2 % Ако има пренос, $10 = 1, иначе 0 или −1 30 0058 610A0A00 CSN $10,$10,0 % Превърни −1 в 0 31 005c 2203030A ADDU $3,$3,$10 % Отчети преноса 32 0060 9F0B0B00 GO $11,$11,0 % Върни управлението HPPA64 LISTING umul128.s page 1 1 ; 128-битовите числа без знак в рег. R23:R24 (Y1:Y0) и R25:R26 (Z1:Z0) да се 2 ; умножат и 256-битовият резултат да се върне в рег. R23:R24:R25:R26 (A:B:C:D). 3 ; Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 4 ; 5 ; PARISC 2.0 няма команда за 64-битово умножение, затова използваме подпрограма 6 ; за умножение на 64-битови числа без знак. Тя връща 128-битово произведение. 7 ; Подаваме ѝ y в FR22 и z в FR23 и тя връща произведението им в R28:29 (ab:cd). 8 ; След умноженията в подпрограмата получаваме следното разположение на данните: 9 ; _____ 10 ; __|_FR7_| 11 ; |_FR8_| 12 ; __|_FR6_| 13 ; |_FR9_| 14 15 0000 2FD13024 UM64X64:FLDDS,MB -8(%SP),%FR4 ; FR4 = y 16 0004 2FD13025 FLDDS,MB -8(%SP),%FR5 ; FR5 = z 17 0008 38A44786 XMPYU %FR5R,%FR4L,%FR6; FR6 = z0 * y1 18 000c 38A45787 XMPYU %FR5R,%FR4R,%FR7; FR7 = z0 * y0 19 0010 38A45708 XMPYU %FR5L,%FR4R,%FR8; FR8 = z1 * y0 20 0014 38A44709 XMPYU %FR5L,%FR4L,%FR9; FR9 = z1 * y1 21 0018 2FD01229 FSTDS,MA %FR9,8(%SP) ; с индекс 1 означаваме старшите 32 бита, 22 001c 0FD130F6 LDD,MB -8(%SP),%R22 ; R22 = z1 * y1 а с 0 – младшите 23 0020 2FD01226 FSTDS,MA %FR6,8(%SP) 24 0024 0FD130F5 LDD,MB -8(%SP),%R21 ; R21 = z0 * y1 25 0028 2FD01228 FSTDS,MA %FR8,8(%SP) 26 002c 0FD130F4 LDD,MB -8(%SP),%R20 ; R20 = z1 * y0 27 0030 2FD01227 FSTDS,MA %FR7,8(%SP) 28 0034 0FD130FC LDD,MB -8(%SP),%R28 ; R28 = z0 * y0 29 0038 F2740800 DEPD,Z %R20,31,32,%R19 ; R19 = z1 * y0 << 32 30 003c 0B93061D ADD %R19,%R28,%R29 ; R29 = (z1 * y0 << 32) + z0 * y0 31 0040 0816073C ADD,DC %R22,%R0,%R28 ; R28 = R22 + пренос = z1 * y1 + пренос 32 0044 F2750800 DEPD,Z %R21,31,32,%R19 ; R19 = z0 * y1 << 32 33 0048 0BB3061D ADD %R19,%R29,%R29 ; R29 += z0 * y1 << 32 34 004c 081C073C ADD,DC %R28,%R0,%R28 ; R28 += пренос 35 0050 DA9303E0 EXTRD,U %R20,31,32,%R19 ; R19 = z1 * y0 >> 32 36 0054 0A7C061C ADD %R28,%R19,%R28 ; R28 += z1 * y0 >> 32 (тук пренос няма никога) 37 0058 DAB303E0 EXTRD,U %R21,31,32,%R19 ; R19 = z0 * y1 >> 32 38 005c 0A7C061C ADD %R28,%R19,%R28 ; R28 += z0 * y1 >> 32 (" " " " " " ) 39 0060 E820D002 BVE,N (%R1) ; R28:R29 = произведението на FR4 (y) и FR5 (z) 40 41 .global umul128,UM64X64 42 umul128: 43 0064 0FCF12F0 STD,MA %R15,8(%SP) ; Съхрани използваните регистри 44 0068 0FD012F0 STD,MA %R16,8(%SP) 45 006c 0FD112F0 STD,MA %R17,8(%SP) 46 0070 0FD212F0 STD,MA %R18,8(%SP) 47 0074 0FD312F0 STD,MA %R19,8(%SP) 48 0078 0FD412F0 STD,MA %R20,8(%SP) 49 007c 0FD512F0 STD,MA %R21,8(%SP) 50 0080 0FD612F0 STD,MA %R22,8(%SP) 51 0084 0FD712F0 STD,MA %R23,8(%SP) ; Връзка между целочислените регистри и тези за 52 0088 E8200000 B,L UM64X64,%R1 ; числа с плаваща запетая има само през паметта 53 008c 0FDA12F0 STD,MA %R26,8(%SP) ; Изпълнява се преди „B,L“! 54 0090 081C0251 COPY %R28,%R17 55 0094 081D0252 COPY %R29,%R18 ; R17:R18 = Z0 * Y1 56 0098 0FD812F0 STD,MA %R24,8(%SP) 57 009c E8200000 B,L UM64X64,%R1 58 00a0 0FDA12F0 STD,MA %R26,8(%SP) 59 00a4 081C025F COPY %R28,%R31 60 00a8 081D025A COPY %R29,%R26 ; R31:R26 = Z0 * Y0 61 00ac 0FD812F0 STD,MA %R24,8(%SP) 62 00b0 E8200000 B,L UM64X64,%R1 63 00b4 0FD912F0 STD,MA %R25,8(%SP) 64 00b8 081C024F COPY %R28,%R15 65 00bc 081D0250 COPY %R29,%R16 ; R15:R16 = Z1 * Y0 66 00c0 0FD712F0 STD,MA %R23,8(%SP) 67 00c4 E8200000 B,L UM64X64,%R1 ; R28:R29 = Z1 * Y1 68 00c8 0FD912F0 STD,MA %R25,8(%SP) 69 00cc 0A5F0619 ADD %R31,%R18,%R25 ; C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 70 00d0 09F10738 ADD,DC %R17,%R15,%R24 ; B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 71 00d4 081C0737 ADD,DC %R28,%R0,%R23 ; A = ст.д.(Z1 * Y1) 72 00d8 0A190619 ADD %R25,%R16,%R25 ; C = ст.(Z0 * Y0) + мл(Z0 * Y1) + мл.(Z1 * Y0) 73 00dc 0BB80738 ADD,DC %R24,%R29,%R24 ; B = ст.(Z0 * Y1) + ст(Z1 * Y0) + мл.(Z1 * Y1) 74 00e0 08170737 ADD,DC %R23,%R0,%R23 75 00e4 0FD130F6 LDD,MB -8(%SP),%R22 ; Възстанови регистрите 76 00e8 0FD130F5 LDD,MB -8(%SP),%R21 77 00ec 0FD130F4 LDD,MB -8(%SP),%R20 78 00f0 0FD130F3 LDD,MB -8(%SP),%R19 79 00f4 0FD130F2 LDD,MB -8(%SP),%R18 80 00f8 0FD130F1 LDD,MB -8(%SP),%R17 81 00fc 0FD130F0 LDD,MB -8(%SP),%R16 82 0100 0FD130EF LDD,MB -8(%SP),%R15 83 0104 E840D002 BVE,N (%R2) ; Произведението A:B:C:D е в R23:R24:R25:R26 TILE-Gx GAS umul128.s page 1 1 # 128-битовите числа без знак в регистри r3:r2 (Y1:Y0) и r1:r0 (Z1:Z0) да се 2 # умножат и 256-битовият резултат да се върне в рег. r3:r2:r1:r0 (A:B:C:D). 3 # Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230. 4 # 5 # TILE-Gx няма команда за 64-битово умножение, затова използваме подпрограма 6 # за умножение на 64-битови числа без знак. Тя връща 128-битово произведение. 7 # Подаваме ѝ в r11 y и в r10 z, а тя връща произведението им в r11:10 (ab:cd). 8 # След умноженията в подпрограмата получаваме следното разположение на данните: 9 # _____ 10 # __|_r11_| 11 # |_r12_| 12 # __|_r13_| 13 # |_r14_| 14 15 0000 8EB2E450 00306A28 UM64X64:MUL_HU_HU r14,r10,r11 # r14 = z1 * y1 16 0008 CDA2EC50 00306A28 MUL_HU_LU r13,r11,r10 # r13 = z0 * y1 с индекс 1 означаваме старшите 17 0010 8CB2EC50 00306A28 MUL_HU_LU r12,r10,r11 # r12 = z1 * y0 32 бита, а с 0 – младшите 18 { MUL_LU_LU r11,r11,r10 # r11 = z0 * y0 19 0018 CBA2F8D0 87010530 SHLI r15,r12,32 } # r15 = z1 * y0 << 32 20 0020 00304851 E5590628 ADD r10,r15,r11 # r10 = (z1 * y0 << 32) + z0 * y0 21 0028 003048D1 47791628 CMPLTU r15,r10,r15 # получи преноса 22 { ADD r11,r14,r15 # r11 = r14 + пренос = z1 * y1 + пренос 23 0030 8BF30CD0 A7010530 SHLI r15,r13,32 } # r15 = z0 * y1 << 32 24 0038 00304851 E5510628 ADD r10,r15,r10 # r10 += z0 * y1 << 32 25 0040 003048D1 47791628 CMPLTU r15,r10,r15 # получи преноса 26 { ADD r11,r11,r15 # r11 += пренос 27 0048 CBF20CD0 87010B30 SHRUI r15,r12,32 } # r15 = z1 * y0 >> 32 28 { ADD r11,r11,r15 # r11 += z1 * y0 >> 32 (тук пренос няма никога) 29 0050 CBF20CD0 A7010B30 SHRUI r15,r13,32 } # r15 = z0 * y1 >> 32 30 { ADD r11,r11,r15 # r11 += z0 * y1 >> 32 (" " " " " " ) 31 0058 CBF20C50 E0766A28 JR lr } # r11:r10 = произведението на r11 (y) и r10 (z) 32 33 .global umul128 34 umul128: 35 { MOVE r16,lr # Съхрани lr, защото „JAL“ ще го промени! 36 0060 D0FD0751 05F83B28 MOVE r10,r0 } # Z0 37 { MOVE r11,r3 # Y1 38 0068 CBF007D1 F9FFFF23 JAL UM64X64 } 39 { MOVE r5,r10 40 0070 85F20751 63F93B28 MOVE r6,r11 } # r6:r5 = Z0 * Y1 41 { MOVE r10,r0 # Z0 42 0078 0AF007D1 45F83B28 MOVE r11,r2 } # Y0 43 0080 00304851 F8FFFF23 JAL UM64X64 44 { MOVE r0,r10 45 0088 80F20751 62F93B28 MOVE r4,r11 } # r4:r0 = C:D = Z0 * Y0 46 { MOVE r10,r1 # Z1 47 0090 4AF007D1 45F83B28 MOVE r11,r2 } # Y0 48 0098 003048D1 F6FFFF23 JAL UM64X64 49 { MOVE r7,r10 50 00a0 87F20751 64F93B28 MOVE r8,r11 } # r8:r7 = Z1 * Y0 51 { MOVE r10,r1 # Z1 52 00a8 4AF007D1 65F83B28 MOVE r11,r3 } # Y1 53 { JAL UM64X64 # r11:r10 = Z1 * Y1 54 00b0 01510C50 F5FFFF23 ADD r1,r4,r5 } # C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 55 { CMPLTU r15,r1,r4 # получи преноса 56 00b8 4F402C50 C1400628 ADD r2,r6,r8 } # B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 57 00c0 00304851 41780628 ADD r2,r2,r15 # B += пренос 58 00c8 003048D1 47301628 CMPLTU r15,r2,r6 # получи преноса 59 { ADD r3,r11,r15 # A = ст.д.(Z1 * Y1) + пренос 60 00d0 C3F20CD0 20380628 ADD r1,r1,r7 }#C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 61 { CMPLTU r15,r1,r7 # получи преноса 62 00d8 4F702C50 41500628 ADD r2,r2,r10}#B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 63 00e0 00304851 41780628 ADD r2,r2,r15 # B += пренос 64 00e8 003048D1 47481628 CMPLTU r15,r2,r9 # получи преноса 65 { ADD r3,r3,r15 # A += пренос 66 00f0 C3F00C50 00726A28 JR r16 } # Върни управлението IA-64 GAS umul128.s page 1 1 // 128-битовите числа без знак в регистри r11:r10 (Y1:Y0) и r9:r8 (Z1:Z0) да се 2 // умножат и 256-битовият резултат да се върне в рег. r11:r10:r9:r8 (A:B:C:D). 3 // Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230 4 5 .global umul128 6 umul128: 7 SETF.SIG f10=r8 8 SETF.SIG f11=r9 // f11:f10 = Z1:Z0 9 SETF.SIG f12=r10 10 0000 08502000 E118B048 00C23100 00000400 SETF.SIG f13=r11 // f13:f12 = Y1:Y0 11 XMPY.HU f6=f10,f13 12 0010 0F602800 E118D058 00C23100 00000400 XMPY.LU f15=f10,f13 // f6:f15 = Z0 * Y1 13 XMPY.HU f14=f12,f10 14 0020 0C000000 01006000 281A7600 00000400 XMPY.LU f10=f12,f10 // f14:f10 = C:D = Z0 * Y0 15 0030 0C000000 0100F000 281A7400 00000400 XMPY.LU f7=f11,f12 16 0040 0C000000 0100E000 30147600 00000400 XMPY.HU f8=f11,f12 // f8:f7 = Z1 * Y0 17 0050 0C000000 0100A000 30147400 00000400 XMPY.LU f9=f11,f13 18 0060 0C000000 01007000 2C187400 00000400 XMPY.HU f13=f11,f13 // f13:f9 = Z1 * Y1 19 0070 0C000000 01008000 2C187600 00000400 GETF.SIG r3=f6 20 0080 0C000000 01009000 2C1A7400 00000400 GETF.SIG r9=f15 // r3:r9 = Z0 * Y1 21 0090 0D000000 0100D000 2C1A7600 00000400 GETF.SIG r2=f14 22 00a0 08181800 E1109078 00C22100 00000400 GETF.SIG r8=f10 // r2:r8 = C:D = Z0 * Y0 23 GETF.SIG r15=f7 24 00b0 08103800 E1108050 00C22100 00000400 GETF.SIG r10=f8 // r10:r15 = Z1 * Y0 25 GETF.SIG r14=f9 26 00c0 08781C00 E110A040 00C22100 00000400 GETF.SIG r11=f13 // r11:r14 = Z1 * Y1 27 ADD r9=r2,r9 // C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 28 00d0 09702400 E110B068 00C22100 00000400 CMP.LTU p6,p7=r9,r2 // Получи преноса 29 ADD r10=r3,r10 // B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 30 00e0 0B480812 00206048 080E6840 31500080 (p6) ADD r10=1,r10 // Отчети преноса 31 CMP.LTU p6,p7=r10,r3 // Получи преноса 32 (p6) ADD r11=1,r11 // A = ст.д.(Z1 * Y1) 33 00f0 CB500414 00216050 0C0E6800 00000400 ADD r9=r9,r15//C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 34 CMP.LTU p6,p7=r9,r15 // Получи преноса 35 0100 C2580416 00219048 3C0040C0 90781CD0 ADD r10=r10,r14//B=ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 36 (p6) ADD r10=1,r10 // Отчети преноса 37 CMP.LTU p6,p7=r10,r14 // Получи преноса 38 0110 0B50281C 00A0A108 28004200 00000400 (p6) ADD r11=1,r11 // Отчети преноса 39 0120 0A30281C 07B4B108 2C004200 00000400 BR.RET.SPTK rp // Върни управлението 39 11000000 01000000 00020080 00008400 E2K GAS umul128.s page 1 1 ! 128-битовите числа без знак в регистри r3:r2 (Y1:Y0) и r1:r0 (Z1:Z0) да се 2 ! умножат и 256-битовият резултат да се върне в рег. r3:r2:r1:r0 (A:B:C:D). 3 ! Алгоритъм: Peter Norton, "Advanced Assembly Language", 1991, стр. 229-230. 4 5 .global umul128 6 umul128: 7 { setwd wsz=10,nfx=1 ! wsz = брой използвани регистри, nfx = неясно! 8 return %ctpr3 ! Подготви връщането към извикващата функция 9 umulhd %r0,%r3,%r6 10 muld %r0,%r3,%r5 ! r6:r5 = Z0 * Y1 11 umulhd %r0,%r2,%r4 12 0000 46C0B06D 86838070 85838021 84828070 80828021 000000F0 00000000 C001C001 C001C001 50010000 muld %r0,%r2,%r0 } ! r4:r0 = C:D = Z0 * Y0 13 { muld %r1,%r2,%r7 14 umulhd %r1,%r2,%r8 ! r8:r7 = Z1 * Y0 15 muld %r1,%r3,%r9 16 umulhd %r1,%r3,%r3 ! r3:r9 = Z1 * Y1 17 0028 3500B07D 87828121 88828170 81858411 89838121 83838170 C001C001 C001C001 addd %r4,%r5,%r1 } ! C = ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) 18 { cmpbdb %r1,%r4,%pred0 ! Получи преноса 19 0048 1200000C 20848121 82888611 00000000 addd %r6,%r8,%r2 } ! B = ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) 20 0058 11000104 82C18211 00000000 00006004 addd %r2,1,%r2 ? %pred0! Отчети преноса 21 0068 01010004 20868221 cmpbdb %r2,%r6,%pred0 ! Получи преноса 22 { addd %r3,1,%r3 ? %pred0! A = ст.д.(Z1 * Y1) 23 0070 1200010C 83C18311 81878111 00006004 addd %r1,%r7,%r1}!C=ст.д.(Z0 * Y0) + мл.д.(Z0 * Y1) + мл.д.(Z1 * Y0) 24 { cmpbdb %r1,%r7,%pred0 ! Получи преноса 25 0080 1200000C 20878121 82898211 00000000 addd %r2,%r9,%r2}!B=ст.д.(Z0 * Y1) + ст.д.(Z1 * Y0) + мл.д.(Z1 * Y1) 26 0090 11000104 82C18211 00000000 00006004 addd %r2,1,%r2 ? %pred0! Отчети преноса 27 00a0 01010004 20898221 cmpbdb %r2,%r9,%pred0 ! Получи преноса 28 { addd %r3,1,%r3 ? %pred0! Отчети преноса 29 00a8 12100104 200C00C0 83C18311 00006004 ct %ctpr3 } ! Върни управлението S/390x LISTING absd128.s page 1 1 # Да се напише подпрограма, която да записва по адрес в регистър 2 абсолютната 2 # стойност (модула) на разликата между двойните думи със знак, чиито адреси са 3 # подадени в регистри 3 и 4. 4 5 .global absd128 6 absd128: 7 0000 EB013000 0004 LMG 0,1,0(3)# Зареди аргументите в регистри 8 0006 EB454000 0004 LMG 4,5,0(4) 9 000c EC040009 4064 CGRJL 0,4,L1 # Сравни старшите – умаляемото е по-малко от умалителя 10 0012 EC04000E 2064 CGRJH 0,4,L2 # Умаляемото е по-голямо от умалителя - извади от него 11 0018 EC15000B A065 CLGRJNL 1,5,L2 # Старшите думи са равни - сравни младшите аналогично 12 001e B90B0051 L1: SLGR 5,1 # Извади младшите 13 0022 B9890040 SLBGR 4,0 # и старшите думи на умаляемото от умалителя 14 0026 EB452000 0024 STMG 4,5,0(2)# Съхрани резултата 15 002c 07FE BR 14 16 002e B90B0015 L2: SLGR 1,5 # Извади младшите 17 0032 B9890004 SLBGR 0,4 # и старшите думи на умалителя от умаляемото 18 0036 EB012000 0024 STMG 0,1,0(2)# Съхрани резултата 19 003c 07FE0707 BR 14 AMD64 GAS absd128.s page 1 1 # Да се напише подпрограма, която да връща в регистри RDX:RAX абсолютната 2 # стойност (модула) на разликата между двойните думи със знак, подадени в 3 # регистри RCX:RDX и RSI:RDI. 4 5 .intel_syntax noprefix 6 .global absd128 7 absd128: 8 0000 4829FA SUB RDX,RDI # Извади младшите 9 0003 4819F1 SBB RCX,RSI # и старшите думи 10 0006 7D0A JGE L1 # O = S = 0 или O = S = 1: модулът е положителен или 0 11 0008 48F7DA NEG RDX # O = 0, S = 1 или O = 1, S = 0: модулът < 0 12 000b 4883D100 ADC RCX,0 # - смени му знака 13 000f 48F7D9 NEG RCX 14 0012 4892 L1: XCHG RAX,RDX 15 0014 4889CA MOV RDX,RCX # Върни абсолютната стойност в RDX:RAX 16 0017 C3 RET 17 # Канонично решение: 18 # CMP RCX,RSI # Сравни старшите думи 19 # JL L1 # Умаляемото е по-малко от умалителя – размени ги 20 # JG L2 # Умаляемото е по-голямо от умалителя – извади ги 21 # CMP RDX,RDI # Старшите думи са равни – сравни младшите 22 # JAE L2 # Умаляемото е не по-малко от умалителя – извади ги 23 #L1: XCHG RCX,RSI # Умаляемото е по-малко от умалителя: размени старшите 24 # XCHG RDX,RDI # и младшите думи на числата 25 #L2: SUB RDX,RDI # Извади младшите 26 # SBB RCX,RSI # и старшите думи 27 # XCHG RAX,RDX 28 # MOV RDX,RCX # Върни абсолютната стойност в RDX:RAX 29 # RET AARCH64 GAS absd128.s page 1 1 // Да се напише подпрограма, която да връща в регистри X1:X0 абсолютната 2 // стойност (модула) на разликата между двойните думи със знак, подадени в 3 // регистри X1:X0 и X3:X2. 4 5 .global absd128 6 absd128: 7 0000 000002EB SUBS X0,X0,X2// Извади младшите 8 0004 210003FA SBCS X1,X1,X3// и старшите думи на умалителя от умаляемото 9 0008 6A000054 BGE L1 // V = N = 0 или V = N = 1: модулът е положителен или 0 10 000c E00300EB NEGS X0,X0 //V = 0, N = 1 или V = 1, N = 0: модулът е отрицателен 11 0010 E10301DA NGC X1,X1 //- смени му знака 12 0014 C0035FD6 L1: RET 13 /* Канонично решение: 14 CMP X1,X3 // Сравни старшите думи 15 BLT L1 // Умаляемото е по-малко от умалителя - извади него 16 BGT L2 // Умаляемото е по-голямо от умалителя - извади от него 17 CMP X0,X2 // Старшите думи са равни - сравни младшите 18 BHS L2 // Умаляемото е не по-малко от умалителя 19 L1: SUBS X0,X2,X0// Умаляемото е по-малко от умалителя: извади младшите 20 SBC X1,X3,X1// и старшите думи на умаляемото от умалителя 21 RET 22 L2: SUBS X0,X0,X2// Извади младшите 23 SBC X1,X1,X3// и старшите думи на умалителя от умаляемото 24 RET 25 */ ARC GAS absd128.s page 1 1 # Да се напише подпрограма, която да връща в регистри r1:r0 абсолютната 2 # стойност (модула) на разликата между двойните думи със знак, подадени в 3 # регистри r1:r0 и r3:r2. 4 5 .global absd128 6 absd128: 7 0000 0258 8080 SUBL.F r0,r0,r2 # Извади младшите 8 0004 0359 C180 SBCL.F r1,r1,r3 # и старшите думи на умалителя от умаляемото 9 0008 E020 CA07 JGE [blink] # V = N = 0 или V = N = 1: модулът е положителен или 0 10 000c 4E58 0080 RSUBL.F r0,r0,0 # V = 0, N = 1 или V = 1, N = 0: модулът е отрицателен 11 0010 4E59 0100 RSUBL r1,r1,0 # - смени му знака 12 0014 4359 0100 SBCL r1,r1,0 # (извади и заема) 13 0018 E07E J_S [blink] 14 /* Канонично решение: 15 BRLTL r1,r3,L1 # Сравни старшите; умаляемото е по-малко от умалителя 16 BRLTL r3,r1,L2 # Умаляемото е по-голямо от умалителя - извади от него 17 BRHSL r0,r2,L2 # Старшите думи са равни - сравни младшите аналогично 18 L1: SUBL.F r0,r2,r0 # Умаляемото е по-малко от умалителя: извади младшите 19 SBCL r1,r3,r1 # и старшите думи на умаляемото от умалителя 20 J_S [blink] 21 L2: SUBL.F r0,r0,r2 # Извади младшите 22 SBCL r1,r1,r3 # и старшите думи на умалителя от умаляемото 23 J_S [blink] 24 */ PPC LISTING absd128.s page 1 1 # Да се напише подпрограма, която да връща в регистри r3:r4 абсолютната 2 # стойност (модула) на разликата между двойните думи със знак, подадени в 3 # регистри r3:r4 и r5:r6. 4 5 .global absd128 6 absd128: 7 0000 7C232800 cmpd r3,r5 # Сравни старшите думи 8 0004 41800010 blt L1 # Умаляемото е по-малко от умалителя - размени ги 9 0008 41810018 bgt L2 # Умаляемото е по-голямо от умалителя - извади ги 10 000c 7C243040 cmpld r4,r6 # Старшите думи са равни - сравни младшите 11 0010 40800010 bge L2 # Умаляемото е не по-малко от умалителя - извади ги 12 0014 7C843010 L1: subfc r4,r4,r6# Умаляемото е по-малко от умалителя: извади младшите 13 0018 7C632910 subfe r3,r3,r5# и старшите думи на умаляемото от умалителя 14 001c 4E800020 blr 15 0020 7C862010 L2: subfc r4,r6,r4# Извади младшите 16 0024 7C651910 subfe r3,r5,r3# и старшите думи на умалителя от умаляемото 17 0028 4E800020 blr SPARC GAS absd128.s page 1 1 ! Да се напише подпрограма, която да връща в регистри %o0:%o1 абсолютната 2 ! стойност (модула) на разликата между двойните думи със знак, подадени в 3 ! регистри %o0:%o1 и %o2:%o3. 4 5 .global absd128 6 absd128: 7 0000 92A2400B subcc %o1,%o3,%o1! Извади младшите и 8 ! subxccc %o0,%o2,%o0! старшите думи на умалителя от умаляемото 9 0004 2A680002 bcs,a %xcc,.+8 ! Ако няма пренос (преход), анулирай изваждането му 10 0008 90222001 dec %o0 ! Иначе го извади от старшата дума 11 000c 90A2000A subcc %o0,%o2,%o0! Извади старшите думи 12 0010 16680006 bge %xcc,L1 ! V = N = 0 или V = N = 1: модулът е положителен или 0 13 0014 01000000 nop 14 0018 92A00009 subcc %g0,%o1,%o1! V = 0, N = 1 или V = 1, N = 0: модулът отрицателен 15 ! subxc %g0,%o0,%o0! - смени му знака 16 001c 2A680002 bcs,a %xcc,.+8 17 0020 90022001 inc %o0 18 0024 90200008 sub %g0,%o0,%o0! За „subxc[cc]“ се изисква поне „SPARC M8“!!! 19 0028 81C3E008 L1: retl 20 002c 01000000 nop 21 /* Канонично решение: 22 cmp %o0,%o2 ! Сравни старшите думи 23 bl %xcc,L1 ! Умаляемото е по-малко от умалителя - извади него 24 nop ! Избегни „Delayed control transfer instruction (DCTI) couple“ 25 bg %xcc,L2 ! Умаляемото е по-голямо от умалителя - извади от него 26 nop !„Delay slot“: решението е взето, но „cmp“ се изпълнява преди „bg“) 27 ! cxbcc %o1,%o3,L2! За „cxbcc“ се изисква поне „SPARC T4“!!! 28 cmp %o1,%o3 ! Старшите думи са равни - сравни младшите 29 bcc %xcc,L2 ! Умаляемото е не по-малко от умалителя 30 nop 31 L1: subcc %o3,%o1,%o1!Умаляемото по-малко от умалителя: извади младшите 32 ! subxc %o2,%o0,%o0! и старшите думи на умаляемото от умалителя 33 bcs,a %xcc,.+8 34 dec %o2 35 sub %o2,%o0,%o0 36 retl 37 nop 38 L2: subcc %o1,%o3,%o1! Извади младшите и 39 ! subxc %o0,%o2,%o0! старшите думи на умалителя от умаляемото 40 bcs,a %xcc,.+8 41 dec %o0 42 sub %o0,%o2,%o0 43 retl 44 nop 45 */ MIPS LISTING absd128.s page 1 1 # Да се напише подпрограма, която да връща в регистри $2:$3 абсолютната 2 # стойност (модула) на разликата между двойните думи със знак, подадени в 3 # регистри $4:$5 и $6:$7. 4 5 .ent absd128 6 .global absd128 7 absd128: 8 0000 0086082A 14200007 00000000 BLT $4,$6,L1# Сравни старшите; умаляемото е по-малко от умалителя 9 000c 00C4082A 14200008 00000000 BGT $4,$6,L2# Умаляемото е по-голямо от умалителя - извади ги 10 0018 00A7082B 10200005 00000000 BGEU $5,$7,L2# Старшите думи са равни - сравни младшите аналогично 11 0024 00E5402B L1: SLTU $8,$7,$5# Получи заема 12 0028 00E5182F DSUBU $3,$7,$5# Умаляемото е по-малко от умалителя: извади младшите 13 DSUBU $2,$6,$4# и старшите думи на умаляемото от умалителя 14 002c 10000004 00C4102F B L3 # as генерира NOP след всеки преход (branch delay slot) 15 0034 00A7402B L2: SLTU $8,$5,$7# Получи заема 16 0038 00A7182F DSUBU $3,$5,$7# Извади младшите 17 003c 0086102F DSUBU $2,$4,$6# и старшите думи на умалителя от умаляемото 18 L3: DSUBU $2,$2,$8# Извади заема 19 0040 03E00008 0048102F JR $31 20 0048 00000000 00000000 .end absd128 RISC-V LISTING absd128.s page 1 1 # Да се напише подпрограма, която да връща в регистри a1:a0 абсолютната 2 # стойност (модула) на разликата между двойните думи със знак, подадени в 3 # регистри a1:a0 и a3:a2. 4 5 .global absd128 6 absd128: 7 0000 63C6D500 BLT a1,a3,L1 # Сравни старшите; умаляемото е по-малко от умалителя 8 0004 63CCB600 BGT a1,a3,L2 # Умаляемото е по-голямо от умалителя - извади ги 9 0008 637AC500 BGEU a0,a2,L2 # Старшите думи са равни - сравни младшите аналогично 10 000c 3337A600 L1: SLTU a4,a2,a0 # Получи заема 11 0010 3305A640 SUB a0,a2,a0 # Умаляемото е по-малко от умалителя: извади младшите 12 0014 B385B640 SUB a1,a3,a1 # и старшите думи на умаляемото от умалителя 13 0018 6F000001 J L3 14 001c 3337C500 L2: SLTU a4,a0,a2 # Получи заема 15 0020 3305C540 SUB a0,a0,a2 # Извади младшите 16 0024 B385D540 SUB a1,a1,a3 # и старшите думи на умалителя от умаляемото 17 0028 B385E540 L3: SUB a1,a1,a4 # Извади заема 18 002c 67800000 RET LOONGARCH64 GAS absd128.s page 1 1 # Да се напише подпрограма, която да връща в регистри r5:r4 абсолютната 2 # стойност (модула) на разликата между двойните думи със знак, подадени в 3 # регистри r5:r4 и r7:r6. 4 5 .global absd128 6 absd128: 7 0000 A70C0060 BLT $r5,$r7,L1# Сравни старшите; умаляемото е по-малко от умалителя 8 0004 E5180060 BGT $r5,$r7,L2# Умаляемото е по-голямо от умалителя: извади от него 9 0008 8614006C BGEU $r4,$r6,L2# Старшите думи са равни - сравни младшите аналогично 10 000c C8901200 L1: SLTU $r8,$r6,$r4# Получи заема 11 0010 C4901100 SUB.D $r4,$r6,$r4# Умаляемото е по-малко от умалителя: извади младши- 12 0014 E5941100 SUB.D $r5,$r7,$r5# те и старшите думи на умаляемото от умалителя 13 0018 00100050 B L3 14 001c 88981200 L2: SLTU $r8,$r4,$r6# Получи заема 15 0020 84981100 SUB.D $r4,$r4,$r6# Извади младшите 16 0024 A59C1100 SUB.D $r5,$r5,$r7# и старшите думи на умалителя от умаляемото 17 0028 A5A01100 L3: SUB.D $r5,$r5,$r8# Извади заема 18 002c 2000004C JIRL $r0,$r1,0 # Да се напише подпрограма, която да записва по адреса в регистър $16 # абсолютната стойност (модула) на разликата между двойните думи със знак, absd128.o: file format ecoff-littlealpha # подадени в регистри $18:$17 и $20:$19. Disassembly of section .text: .ent absd128 .globl absd128 0000000000000000 : absd128: 0: a0 09 54 42 cmplt a2,a4,v0 cmplt $18,$20,$0# Сравни старшите думи и ако умаляемото е по-малко от 4: 04 00 00 f4 bne v0,18 bne $0,L1 # умалителя, извади умаляемото от умалителя 8: a0 09 92 42 cmplt a4,a2,v0 cmplt $20,$18,$0# Ако умаляемото е по-голямо от умалителя, c: 06 00 00 f4 bne v0,28 bne $0,L2 # извади умалителя от умаляемото 10: a0 07 71 42 cmpule a3,a1,v0 cmpule $19,$17,$0# Старшите думи са равни - сравни младшите 14: 04 00 00 f4 bne v0,28 bne $0,L2 # Умаляемото е по-голямо от или равно на умалителя 18: 21 05 71 42 subq a3,a1,t0 L1: cmpult $19,$17,$0# Получи заема 1c: a0 03 71 42 cmpult a3,a1,v0 subq $19,$17,$1# Умаляемото е по-малко от умалителя: извади младшите 20: 22 05 92 42 subq a4,a2,t1 subq $20,$18,$2# и старшите думи на умаляемото от умалителя 24: 03 00 e0 c3 br 34 br $31,L3 28: a0 03 33 42 cmpult a1,a3,v0 L2: cmpult $17,$19,$0# Получи заема 2c: 21 05 33 42 subq a1,a3,t0 subq $17,$19,$1# Извади младшите 30: 22 05 54 42 subq a2,a4,t1 subq $18,$20,$2# и старшите думи на умалителя от умаляемото 34: 22 05 40 40 subq t1,v0,t1 L3: subq $2,$0,$2 # Извади заема 38: 00 00 30 b4 stq t0,0(a0) stq $1,0($16) # Запиши младшата 3c: 08 00 50 b4 stq t1,8(a0) stq $2,8($16) # и старшата дума на резултата 40: 01 80 fa 6b ret zero,(ra),0x1 ret 44: 1f 04 ff 47 nop .end absd128 48: 00 00 fe 2f unop 4c: 1f 04 ff 47 nop GAS for MMIX absd128.s page 1 1 % Да се напише подпрограма, която да връща в регистри $1:$0 абсолютната 2 % стойност (модула) на разликата между двойните думи със знак, чиито адреси са 3 % подадени в регистри $0 и $1. 4 5 .global absd128 6 absd128: 7 0000 8D020000 LDO $2,$0,0 % Зареди двойните думи в регистри 8 0004 8D030008 LDO $3,$0,8 % MMIX е big-endian (BE) 9 0008 8D040100 LDO $4,$1,0 % $2:$3 – умаляемо (засега) 10 000c 8D050108 LDO $5,$1,8 % $4:$5 – умалител" " " 11 0010 30060204 CMP $6,$2,$4 % Сравни старшите думи и ако умаляемото е по-малко от 12 0014 40060004 BN $6,L1 % умалителя, извади умаляемото от умалителя, а ако 13 0018 44060008 BP $6,L2 % е по-голямо от него, извади умалителя от умаляемото 14 001c 32060305 CMPU $6,$3,$5 % Старшите думи за равни – сравни младшите 15 0020 48060006 BNN $6,L2 % Умаляемото е по-голямо от или равно на умалителя 16 0024 32060305 L1: CMPU $6,$3,$5 % Ако има заем, $6 = 1, иначе 0 или −1 17 0028 61060600 CSN $6,$6,0 % Превърни −1 в 0 18 002c 26000503 SUBU $0,$5,$3 % Умаляемото е по-малко от умалителя: извади младшите 19 0030 26010402 SUBU $1,$4,$2 % и старшите думи на умаляемото от умалителя 20 0034 F0000005 JMP L3 21 0038 32060503 L2: CMPU $6,$5,$3 % Ако има заем, $6 = 1, иначе 0 или −1 22 003c 61060600 CSN $6,$6,0 % Превърни −1 в 0 23 0040 26000305 SUBU $0,$3,$5 % Извади младшите 24 0044 26010204 SUBU $1,$2,$4 % и старшите думи на умалителя от умаляемото 25 0048 26010106 L3: SUBU $1,$1,$6 % Извади заема 26 004c F8020000 POP 2,0 % Върни абсолютната стойност на разликата в $1:$0 HPPA64 LISTING absd128.s page 1 1 ; Да се напише подпрограма, която да връща в регистри %R28:%R29 абсолютната 2 ; стойност (модула) на разликата между двойните думи със знак, подадени в 3 ; регистри %R26:%R25 и %R24:%R23. 4 5 .global absd128 6 absd128: 7 0000 0AF9041D SUB %R25,%R23,%R29 ; Извади младшите 8 0004 0B1A453C SUB,DB,*< %R26,%R24,%R28; и старшите думи 9 0008 E840D002 BVE,N (%R2) ; Върни модула, освен ако %R26 е бил < от %R24 10 000c 0BA0041D SUB %R0,%R29,%R29 ; Смени знака на модула 11 0010 E840D000 BVE (%R2) ; Върни модула (изпълнява се след „SUB,DB“!) 12 0014 0B80053C SUB,DB %R0,%R28,%R28 13 ; Канонично решение: 14 ; CMPB,*< %R26,%R24,L1; Умаляемото е по-малко от умалителя: извади него 15 ; NOP 16 ; CMPB,*< %R24,%R26,L2; Умаляемото по-голямо от умалителя: извади от него 17 ; NOP 18 ; CMPB,*<<= %R23,%R25,L2; Старшите думи са равни - сравни младшите 19 ; NOP 20 ;L1: SUB %R23,%R25,%R29; Умаляемото по-малко от умалителя: извади млад- 21 ; BVE (%R2) ; (изпълнява се след „SUB,DB“!) 22 ; SUB,DB %R24,%R26,%R28; шите и старшите думи на умаляемото от умалителя 23 ;L2: SUB %R25,%R23,%R29; Извади младшите... 24 ; BVE (%R2) ; (изпълнява се след „SUB,DB“!) 25 ; SUB,DB %R26,%R24,%R28; ...и старшите думи на умалителя от умаляемото TILE-Gx GAS absd128.s page 1 1 # Да се напише подпрограма, която да връща в регистър r0 абсолютната стойност 2 # (модула) на разликата между двойните думи със знак, подадени в регистри 3 # r1:r0 и r3:r2. 4 5 .global absd128 6 absd128: 7 0000 00304851 22181428 CMPLTS r4,r1,r3 # Сравни старшите думи и ако умаляемото е по-малко от 8 { BNEZ r4,L1 # умалителя, извади умаляемото от умалителя 9 0008 C41028D0 8100C017 CMPLTS r4,r3,r1 }# Ако умаляемото е по-голямо от умалителя, 10 { BNEZT r4,L2 # извади умалителя от умаляемото 11 0010 84002450 82008017 CMPLEU r4,r2,r0 }# Старшите думи са равни - сравни младшите 12 0018 003048D1 8100C017 BNEZ r4,L2 # Умаляемото е по-голямо от или равно на умалителя 13 L1: { CMPLTU r4,r2,r0 # Получи заема 14 0020 84002C50 40006828 SUB r0,r2,r0 }# Умаляемото е по-малко от умалителя: извади младшите 15 { SUB r1,r3,r1 # и старшите думи на умаляемото от умалителя 16 0028 C11044D1 01000024 J L3 } 17 L2: { CMPLTU r4,r0,r2 # Получи заема 18 0030 04202C50 00106828 SUB r0,r0,r2 }# Извади младшите 19 0038 003048D1 20186828 SUB r1,r1,r3 # и старшите думи на умалителя от умаляемото 20 L3: { SUB r1,r1,r4 # Извади заема 21 0040 41404451 E0766A28 JR lr } IA-64 GAS absd128.s page 1 1 // Да се напише подпрограма, която да връща в регистри r9:r8 абсолютната 2 // стойност (модула) на разликата между двойните думи със знак, подадени 3 // в регистри in1:in0 и in3:in2. 4 5 .global absd128 6 absd128: 7 ALLOC loc0=ar.pfs,4,1,0,0 8 CMP.LT p6,p7=in1,in3 // Сравни старшите думи и ако са различни, 9 CMP.LT p7,p6=in3,in1 // извади по-малката двойна дума от по-голямата 10 0000 0220150A 80056008 8D0E60E0 300A19C0 CMP.EQ p8,p9=in1,in3 // Равни ли са старшите думи? 11 (p8) CMP.LEU p6,p7=in0,in2 // Да, сравни младшите 12 (p6) CMP.LTU p8,p9=in2,in0 // Получи заема от изваждането на умаляемото 13 0010 0B408446 09387210 810C6800 00000400 (p7) CMP.LTU p8,p9=in0,in2 // " " " " " " " " умалителя 14 (p6) SUB r8=in2,in0 // Умаляемото по-малко от умалителя: извади от 15 0020 C0408840 09F48100 89126803 21021580 (p6) SUB r9=in3,in1 // него младшата и старшата думи на умаляемото 16 (p7) SUB r8=in0,in2 // В противен слчай извади младшата и 17 (p7) SUB r9=in1,in3 // старшата думи на умалителя от умаляемото 18 0030 C1488C42 05E08100 890AC023 111A1580 (p8) SUB r9=r9,r0,1 // Извади заема 19 0040 11492400 04200000 00020080 00008400 BR.RET.SPTK rp E2K GAS absd128.s page 1 1 ! Да се напише подпрограма, която да връща в регистри r1:r0 абсолютната 2 ! стойност (модула) на разликата между двойните думи със знак, подадени в 3 ! регистри r1:r0 и r3:r2. 4 5 .global absd128 6 absd128: 7 { return %ctpr3 ! Подготви връщането към извикващата функция 8 cmpldb %r1,%r3,%pred0 ! Сравни старшите думи и ако са различни, 9 cmpldb %r3,%r1,%pred1 ! извади по-малката двойна дума от по-голямата 10 0000 2440002C C0838121 C1818321 42838121 000000F0 00000000 cmpedb %r1,%r3,%pred2 }! Равни ли са старшите думи? 11 { cmpbedb %r0,%r2,%pred0 ? %pred2 ! Да, сравни младшите 12 0018 1200010C 60828021 21808221 0000620C cmpbdb %r2,%r0,%pred1 ? %pred2 } 13 { cmpbdb %r2,%r0,%pred2 ? %pred0 ! Заем от изваждането на умаляемото 14 cmpbdb %r0,%r2,%pred2 ? %pred1 ! " " " " " " умалителя 15 subd %r2,%r0,%r0 ? %pred0! Умаляемото по-малко от умалителя: намали 16 subd %r3,%r1,%r1 ? %pred0! го с младшата и старша думи на умаляемото 17 subd %r0,%r2,%r0 ? %pred1! В противен слчай извади младшата и 18 0028 460002FC 22808221 22828021 80808213 81818313 80828013 81838113 00000000 61586044 61086014 subd %r1,%r3,%r1 ? %pred1 }! старша думи на умалителя от умаляемото 19 { subd %r1,1,%r1 ? %pred2 ! Извади заема 20 0050 12100104 200C00C0 81C18113 00006204 ct %ctpr3 } ! Върни управлението S/390x LISTING sqrt128.s page 1 1 # Да се напише подпрограма, която да връща в регистър 2 цялата част на 2 # квадратния корен на двойната дума, чийто адрес е подаден в същия регистър, 3 # която част е равна на броя последователни нечетни числа, които могат да се 4 # извадят от това число. 5 6 .global sqrt128 7 sqrt128: 8 0000 EB232000 0004 LMG 2,3,0(2)# Зареди аргумента в регистри 9 0006 B9820000 XGR 0,0 # Подготви старшата дума на събираемото за цикъла 10 000a A749FFFF LGHI 4,-1 # Задай начална стойност -1 на 65-битовия умалител 11 000e B9040054 LGR 5,4 12 0012 C25A0000 0002 L1: ALGFI 5,2 # Получи следващото нечетно число 13 0018 B9880040 ALCGR 4,0 14 001c B90B0035 SLGR 3,5 # Извади младшите думи 15 0020 B9890024 SLBGR 2,4 # Извади старшите думи 16 0024 A734FFF7 BRC 3,L1 # Ако още няма пренос (0 или не), следваща итерация 17 0028 EB250001 000C SRLG 2,5,1 # Раздели на 2 последното нечетно число, заменяйки най- 18 002e EC240000 3F55 RISBG 2,4,0,0,63#старшия бит на мл. дума с най-младшия на старшата 19 0034 07FE0707 BR 14 # Рег. 2 = броя извадени последователни нечетни числа AMD64 GAS sqrt128.s page 1 1 # Да се напише подпрограма, която да връща в регистър RAX цялата част на 2 # квадратния корен на числото в регистрите RSI:RDI, която цяла част е равна на 3 # броя последователни нечетни числа, които могат да се извадят от това число. 4 5 .intel_syntax noprefix 6 .global sqrt128 7 sqrt128: 8 0000 48C7C0FF FFFFFF MOV RAX,-1 # Задай начална стойност -1 на 65-битовия умалител 9 0007 4889C2 MOV RDX,RAX # в RDX:RAX 10 000a 4883C002 L1: ADD RAX,2 # Получи следващото нечетно число 11 000e 4883D200 ADC RDX,0 12 0012 4829C7 SUB RDI,RAX # Извади младшите думи 13 0015 4819D6 SBB RSI,RDX # Извади старшите думи 14 0018 73F0 JNC L1 # Ако още няма пренос, направи следващата итерация 15 001a 480FACD0 01 SHRD RAX,RDX,1#Раздели така получения умалител на 2 16 001f C3 RET # RAX = броя извадени последователни нечетни числа AARCH64 GAS sqrt128.s page 1 1 // Да се напише подпрограма, която да връща в регистър X0 цялата част на 2 // квадратния корен на числото в регистрите X1:X0, която цяла част е равна на 3 // броя последователни нечетни числа, които могат да се извадят от това число. 4 5 .global sqrt128 6 sqrt128: 7 0000 E3033FAA MVN X3,XZR // Задай начална стойност -1 на 65-битовия умалител 8 0004 E20303AA MOV X2,X3 9 0008 420800B1 L1: ADDS X2,X2,#2// Получи следващото нечетно число 10 000c 63001F9A ADC X3,X3,XZR 11 0010 000002EB SUBS X0,X0,X2// Извади младшите думи 12 0014 210003FA SBCS X1,X1,X3// Извади старшите думи 13 0018 82FFFF54 BHS L1 // Ако още няма пренос (има заем), следваща итерация 14 001c 6004C293 EXTR X0,X3,X2,#1// Раздели така получения умалител на 2 15 0020 C0035FD6 RET // X0 = броя извадени последователни нечетни числа ARC GAS sqrt128.s page 1 1 # Да се напише подпрограма, която да връща в регистър r0 цялата част на 2 # квадратния корен на числото в регистрите r1:r0, която цяла част е равна на 3 # броя последователни нечетни числа, които могат да се извадят от това число. 4 5 .global sqrt128 6 sqrt128: 7 0000 6F5B 0A00 NOTL r3,0 # Задай начална стойност -1 на 65-битовия умалител 8 0004 6442 MOVL_S r2,r3 9 0006 405A 8280 L1: ADDL.F r2,r2,2 # Получи следващото нечетно число 10 000a 415B 0300 ADCL r3,r3,0 11 000e 0258 8080 SUBL.F r0,r0,r2 # Извади младшите думи 12 0012 0359 C180 SBCL.F r1,r1,r3 # Извади старшите думи 13 0016 79F7 BHS_S L1 # Ако още няма пренос (има заем), следваща итерация 14 0018 615B 4380 LSRL.F r3,r3,1 # Раздели така получения умалител на 2 15 001c 615A 4000 LSRL r0,r2,1 # Уви, в ARCv3 няма команда „RRCL“! 16 0020 CF58 E50F BSETL.CS r0,r0,63# r0 = броя извадени последователни нечетни числа 17 0024 E07E J_S [blink] PPC LISTING sqrt128.s page 1 1 # Да се напише подпрограма, която да връща в регистър r3 цялата част на 2 # квадратния корен на числото в регистрите r3:r4, която цяла част е равна на 3 # броя последователни нечетни числа, които могат да се извадят от това число. 4 5 .global sqrt128 6 sqrt128: 7 0000 38A0FFFF li r5,-1 # Задай начална стойност -1 на 65-битовия умалител 8 0004 7CA62B78 mr r6,r5 9 0008 30C60002 L1: addic r6,r6,2 # Получи следващото нечетно число 10 000c 7CA50194 addze r5,r5 11 0010 7C862010 subfc r4,r6,r4# Извади младшите думи 12 0014 7C651910 subfe r3,r5,r3# Извади старшите думи 13 0018 7CE73911 subfe. r7,r7,r7# Още ли няма пренос (има заем)? 14 001c 4182FFEC beq+ L1 # Да, следваща итерация 15 0020 78C3F842 srdi r3,r6,1 # Не, раздели така получения умалител на 2 16 0024 78A3F80E rldimi r3,r5,63,0# Копирай най-младшия бит на мястото на най-старшия 17 0028 4E800020 blr # r3 = броя извадени последователни нечетни числа SPARC GAS sqrt128.s page 1 1 ! Да се напише подпрограма, която да връща в регистър %o0 цялата част на 2 ! квадратния корен на числото в регистрите %o0:%o1, която цяла част е равна на 3 ! броя последователни нечетни числа, които могат да се извадят от това число. 4 5 .global sqrt128 6 sqrt128: 7 0000 94103FFF mov -1,%o2 ! Задай начална стойност -1 на 33-битовия умалител 8 0004 9610000A mov %o2,%o3 9 0008 9682E002 L1: addcc %o3,2,%o3 ! Получи следващото нечетно число 10 ! addxc %o2,%g0,%o2! За „addxc[cc]“ се изисква поне „SPARC T3“!!! 11 000c 2A600002 bcs,a,pn %xcc,.+8! Ако няма пренос (преход), анулирай добавянето му 12 0010 9402A001 inc %o2 13 0014 92A2400B subcc %o1,%o3,%o1! Извади младшите думи 14 ! subxccc %o0,%o2,%o0! Извади старшите думи 15 0018 2A600002 bcs,a,pn %xcc,.+8! Ако няма пренос (преход), анулирай изваждането му 16 001c 90A22001 deccc %o0 17 0020 3A680002 bcc,a,pt %xcc,.+8! Ако има " " " " " " " " " 18 0024 90A2000A subcc %o0,%o2,%o0! За „subxc[cc]“ се изисква поне „SPARC M8“!!! 19 0028 1A6FFFF8 bcc,pt %xcc,L1 ! Ако още няма пренос (заем), следваща итерация 20 002c 01000000 nop 21 0030 9132F001 srlx %o3,1,%o0 ! Раздели така получения умалител на 2 22 0034 952AB03F sllx %o2,63,%o2 ! Копирай най-младшия бит на мястото на най-старшия 23 0038 81C3E008 retl ! Изпълнява се след „or“! 24 003c 9012000A or %o0,%o2,%o0! %o0 = броя извадени последователни нечетни числа MIPS LISTING sqrt128.s page 1 1 # Да се напише подпрограма, която да връща в регистър $2 цялата част на 2 # квадратния корен на числото в регистрите $4:$5, която цяла част е равна на 3 # броя последователни нечетни числа, които могат да се извадят от това число. 4 5 .ent sqrt128 6 .global sqrt128 7 sqrt128: 8 0000 2406FFFF LI $6,-1 # Задай начална стойност -1 на 65-битовия умалител 9 0004 00C03825 MOVE $7,$6 10 0008 64E70002 L1: DADDIU $7,$7,2 # Получи следващото нечетно число - в младшата 11 000c 2CE80002 SLTIU $8,$7,2 # (получи преноса) 12 0010 00C8302D DADDU $6,$6,$8# и в старшата дума 13 0014 00A7402B SLTU $8,$5,$7# Получи заема за младшите думи 14 0018 00A7282F DSUBU $5,$5,$7# Извади ги 15 001c 0086082B 14200007 00000000 BLTU $4,$6,L2# Ако ще има заем за старшите думи, край на цикъла 16 0028 0086202F DSUBU $4,$4,$6# Извади старшите думи 17 002c 0088082B 14200003 00000000 BLTU $4,$8,L2# Може ли да се извади и заемът за младшите думи? 18 DSUBU $4,$4,$8# Да, извади го 19 0038 1000FFF3 0088202F B L1 # и продължи цикъла 20 0040 0007107A L2: DSRL $2,$7,1 # Не, раздели така получения умалител на 2 21 DINSU $2,$6,63,1# Копирай най-младшия бит на мястото на най-старшия 22 0044 03E00008 7CC2FFC6 JR $31 # $2 = броя извадени последователни нечетни числа 23 004c 00000000 .end sqrt128 RISC-V LISTING sqrt128.s page 1 1 # Да се напише подпрограма, която да връща в регистър a0 цялата част на 2 # квадратния корен на числото в регистрите a1:a0, която цяла част е равна на 3 # броя последователни нечетни числа, които могат да се извадят от това число. 4 5 .global sqrt128 6 sqrt128: 7 0000 9306F0FF LI a3,-1 # Задай начална стойност -1 на 65-битовия умалител 8 0004 13860600 MV a2,a3 9 0008 13062600 L1: ADDI a2,a2,2 # Получи следващото нечетно число - в младшата 10 000c 13372600 SLTIU a4,a2,2 # (получи преноса) 11 0010 B386E600 ADD a3,a3,a4 # и в старшата дума 12 0014 3337C500 SLTU a4,a0,a2 # Получи заема за младшите думи 13 0018 3305C540 SUB a0,a0,a2 # Извади ги 14 001c 63EAD500 BLTU a1,a3,L2 # Ако ще има заем за старшите думи, край на цикъла 15 0020 B385D540 SUB a1,a1,a3 # Извади старшите думи 16 0024 63E6E500 BLTU a1,a4,L2 # Може ли да се извади и заемът за младшите думи? 17 0028 B385E540 SUB a1,a1,a4 # Да, извади го 18 002c 6FF0DFFD J L1 # и продължи цикъла 19 0030 13551600 L2: SRLI a0,a2,1 # Не, раздели така получения умалител на 2 20 0034 9396F603 SLLI a3,a3,63 # Копирай най-младшия бит на мястото на най-старшия 21 0038 3365D500 OR a0,a0,a3 22 003c 67800000 RET # a0 = броя извадени последователни нечетни числа LOONGARCH64 GAS sqrt128.s page 1 1 # Да се напише подпрограма, която да връща в регистър r4 цялата част на 2 # квадратния корен на числото в регистрите r5:r4, която цяла част е равна на 3 # броя последователни нечетни числа, които могат да се извадят от това число. 4 5 .global sqrt128 6 sqrt128: 7 0000 07001400 NOR $r7,$r0,$r0 # Задай начална стойност -1 на 33-битовия умалител 8 0004 06001400 NOR $r6,$r0,$r0 9 0008 C608C002 L1: ADDI.D $r6,$r6,2 # Получи следващото нечетно число - в младшата 10 000c C8084002 SLTUI $r8,$r6,2 # (получи преноса) 11 0010 E7A01000 ADD.D $r7,$r7,$r8 # и в старшата дума 12 0014 88981200 SLTU $r8,$r4,$r6 # Получи заема за младшите думи 13 0018 84981100 SUB.D $r4,$r4,$r6 # Извади ги 14 001c A7140068 BLTU $r5,$r7,L2 # Ако ще има заем за старшите думи, край на цикъла 15 0020 A59C1100 SUB.D $r5,$r5,$r7 # Извади старшите думи 16 0024 A80C0068 BLTU $r5,$r8,L2 # Може ли да се извади и заемът за младшите думи? 17 0028 A5A01100 SUB.D $r5,$r5,$r8 # Да, извади го 18 002c FFDFFF53 B L1 # и продължи цикъла 19 0030 C4044500 L2: SRLI.D $r4,$r6,1 # Не, раздели така получения умалител на 2 20 0034 E4FCBF00 BSTRINS.D $r4,$r7,63,63# Копирай най-младшия бит в най-старшия 21 0038 2000004C JIRL $r0,$r1,0 # r4 = броя извадени последователни нечетни числа # Да се напише подпрограма, която да връща в регистър $0 цялата част на # квадратния корен на числото в регистрите $17:$16, която цяла част е равна на sqrt128.o: file format ecoff-littlealpha # броя последователни нечетни числа, които могат да се извадят от това число. Disassembly of section .text: .ent sqrt128 .globl sqrt128 0000000000000000 : sqrt128: 0: ff ff 1f 20 lda v0,-1(zero) lda $0,-1($31) # Задай начална стойност -1 на 65-битовия умалител 4: 01 04 e0 47 mov v0,t0 bis $31,$0,$1 8: 00 54 00 40 addq v0,0x2,v0 L1: addq $0,2,$0 # Получи следващото нечетно число - в младшата c: a2 53 00 40 cmpult v0,0x2,t1 cmpult $0,2,$2 # (получи преноса) 10: 01 04 22 40 addq t0,t1,t0 addq $1,$2,$1 # и в старшата дума 14: a3 03 21 42 cmpult a1,t0,t2 cmpult $16,$0,$2 # Получи заема за младшите думи 18: a2 03 00 42 cmpult a0,v0,t1 subq $16,$0,$16 # Извади ги 1c: 30 05 00 42 subq a0,v0,a0 cmpult $17,$1,$3 # Ще има ли заем за старшите думи? 20: 05 00 60 f4 bne t2,38 bne $3,L2 # Да, край на цикъла 24: 31 05 21 42 subq a1,t0,a1 subq $17,$1,$17 # Не, извади старшите думи 28: a3 03 22 42 cmpult a1,t1,t2 cmpult $17,$2,$3 # Може ли да се извади и заемът за младшите думи? 2c: 02 00 60 f4 bne t2,38 bne $3,L2 # Не, край на цикъла 30: 31 05 22 42 subq a1,t1,a1 subq $17,$2,$17 # Да, извади го 34: f4 ff ff c3 br 8 br $31,L1 # и продължи цикъла 38: 80 36 00 48 srl v0,0x1,v0 L2: srl $0,1,$0 # Раздели така получения умалител на 2 3c: 21 f7 27 48 sll t0,0x3f,t0 sll $1,63,$1 # Копирай най-младшия бит на мястото на най-старшия 40: 00 04 01 44 or v0,t0,v0 bis $0,$1,$0 # $0 = броя извадени последователни нечетни числа 44: 01 80 fa 6b ret zero,(ra),0x1 ret 48: 1f 04 ff 47 nop .end sqroot128 4c: 00 00 fe 2f unop GAS for MMIX sqrt128.s page 1 1 % Да се напише подпрограма, която да връща в регистър $0 цялата част на 2 % квадратния корен на двойната дума, чийто адрес е подаден в същия регистър, 3 % която цяла част е равна на броя последователни нечетни числа, които могат да 4 % се извадят от това число. 5 6 .global sqrt128 7 sqrt128: 8 0000 8D020000 LDO $2,$0,0 % Зареди старшата 9 0004 8D030008 LDO $3,$0,8 % и младшата дума на подкореновата величина 10 0008 CE000000 NXOR $0,$0,$0 % Задай начална стойност −1 на 65-битовия умалител 11 000c C1010000 OR $1,$0,0 12 0010 23010102 L1: ADDU $1,$1,2 % Получи следващото нечетно число - в младшата... 13 0014 33040102 CMPU $4,$1,2 % (ако има пренос, $4 = −1, иначе 1; 14 0018 65040400 CSP $4,$4,0 % превърни 1 в 0) 15 001c 26000004 SUBU $0,$0,$4 % ...и в старшата дума 16 0020 32040103 CMPU $4,$1,$3 % Има ли заем за младшите думи, $4 = 1, иначе 0 или −1 17 0024 61040400 CSN $4,$4,0 % (превърни −1 в 0) 18 0028 26030301 SUBU $3,$3,$1 % Извади младшите думи 19 002c 26050200 SUBU $5,$2,$0 % Има ли заем за старшите думи, $5 = −1, иначе 0 или 1 20 0030 40050006 BN $5,L2 % Има – край на цикъла 21 0034 26020200 SUBU $2,$2,$0 % Няма, извади старшите думи 22 0038 32050204 CMPU $5,$2,$4 % Може ли да се извади и заемът за младшите думи? 23 003c 40050003 BN $5,L2 % Не, край на цикъла 24 0040 26020204 SUBU $2,$2,$4 % Да, извади го 25 0044 F1FFFFF3 JMP L1 % и продължи цикъла 26 0048 3F010101 L2: SRU $1,$1,1 % Раздели така получения умалител на 2 27 004c 3B00003F SLU $0,$0,63 % Копирай най-младшия бит на мястото на най-старшия 28 0050 C0000001 OR $0,$0,$1 % $0 = броя извадени последователни нечетни числа 29 0054 F8010000 POP 1,0 % Върни управлението на извикващата програма HPPA64 LISTING sqrt128.s page 1 1 ; Да се напише подпрограма, която да връща в регистър %R28 цялата част на 2 ; квадратния корен на числото в регистрите %R26:%R25, която цяла част е равна 3 ; на броя последователни нечетни числа, които могат да се извадят от това число 4 5 .global sqrt128 6 sqrt128: 7 0000 34173FFF LDI -1,%R23 ; Задай начална стойност -1 на 65-битовия умалител 8 0004 08170258 COPY %R23,%R24 9 0008 B6F70004 L1: ADDI 2,%R23,%R23 ; Получи следващото нечетно число 10 000c 0B000738 ADD,DC %R0,%R24,%R24 11 0010 0AF90419 SUB %R25,%R23,%R25 ; Извади младшите думи 12 0014 0B1A853A SUB,DB,*<< %R26,%R24,%R26; Извади старшите думи и анулирай „B“ при заем 13 0018 E81F1FD7 B,N L1 ; Следваща итерация (командата „BVE“ се анулира) 14 001c E840D000 BVE (%R2) ; %R28 = броя извадени последователни нечетни числа 15 0020 D2F80FDC SHRPD %R24,%R23,1,%R28; Раздели умалителя на 2 (изп. се преди „BVE“!) TILE-Gx GAS sqrt128.s page 1 1 # Да се напише подпрограма, която да връща в регистър r0 цялата част на 2 # квадратния корен на числото в регистрите r1:r0, която цяла част е равна на 3 # броя последователни нечетни числа, които могат да се извадят от това число. 4 5 .global sqrt128 6 sqrt128: 7 { MOVEI r2,-1 # Задай начална стойност -1 на 65-битовия умалител 8 0000 C2FF1FC0 E1FF0F18 MOVEI r3,-1 } 9 0008 00304851 41100818 L1: ADDI r2,r2,2 # Получи следващото нечетно число - в младшата 10 0010 00304851 42103018 CMPLTUI r4,r2,2 # (получи преноса) 11 { ADD r3,r3,r4 # и в старшата дума 12 0018 C3400C50 02101628 CMPLTU r4,r0,r2 } # Получи заема за младшите думи 13 { SUB r0,r0,r2 # Извади ги 14 0020 002044D1 22181628 CMPLTU r5,r1,r3 } # Ще има ли заем за старшите думи? 15 { BNEZ r5,L2 # Да, край на цикъла 16 0028 41304451 A200C017 SUB r1,r1,r3 } # Не, извади старшите думи 17 0030 003048D1 22201628 CMPLTU r5,r1,r4 # Може ли да се извади и заемът за младшите думи? 18 { BNEZ r5,L2 # Не, край на цикъла 19 0038 41404451 A100C017 SUB r1,r1,r4 } # Да, извади го 20 0040 003048D1 FCFFFF27 J L1 # и продължи цикъла 21 0048 00304851 40080A30 L2: SHRUI r0,r2,1 # Раздели така получения умалител на 2 22 { BFINS r0,r3,63,63# Копирай най-младшия бит на мястото на най-старшия 23 0050 C0F0FF36 E0766A28 JR lr } # r0 = броя извадени последователни нечетни числа IA-64 GAS sqrt128.s page 1 1 // Да се напише подпрограма, която да връща в регистър r8 цялата част на 2 // квадратния корен на числото в регистрите in1:in0, която цяла част е равна на 3 // броя последователни нечетни числа, които могат да се извадят от това число. 4 5 .global sqrt128 6 sqrt128: 7 ALLOC loc3=ar.pfs,2,4,0,0 8 SUB loc0=r0,r0,1 // Задай начална стойност -1 на 65-битовия 9 SUB loc1=r0,r0,1 // умалител 10 0000 0128190C 80052002 00084060 04001080 L1: ADD loc0=2,loc0 // Получи следващото нечетно число - в младшата 11 CMP.GTU p6,p7=2,loc0 // (получи преноса) 12 (p6) ADD loc1=loc1,r0,1 // и в старшата дума 13 0010 0B100944 00217008 880C6A00 00000400 CMP.LTU p8,p9=in0,loc0 // Получи заема за младшите думи 14 SUB in0=in0,loc0 // Извади ги 15 0020 C1188D00 01208000 89126800 04121580 (p8) MOV loc2=1 // Запази заема " " " " 16 (p9) MOV loc2=r0 17 CMP.LTU p6,p7=in1,loc1 // Ще има ли заем за старшите думи? 18 0030 01210500 00644202 000042C0 101A1DD0 (p7) SUB in1=in1,loc1 // Не, извади ги и провери дали може да се 19 (p7) CMP.LTU p6,p7=in1,loc2 // извади и заемът за младшите думи 20 (p7) SUB in1=in1,loc2 // Ако може, го извади 21 0040 EB088546 05E06108 910E6800 00000400 (p7) BR L1 // и продължи цикъла 22 SHRP r8=loc1,loc0,1 // Раздели така получения умалител на 2; r8 = 23 0050 F0088548 05200000 00028003 C0FFFF48 BR.RET.SPTK rp // броя извадени последователни нечетни числа 23 11000000 01008018 89022B80 00008400 E2K GAS sqrt128.s page 1 1 ! Да се напише подпрограма, която да връща в регистър r0 цялата част на 2 ! квадратния корен на числото в регистрите r1:r0, която цяла част е равна на 3 ! броя последователни нечетни числа, които могат да се извадят от това число. 4 5 .global sqrt128 6 sqrt128: 7 { setwd wsz=5,nfx=1 ! wsz = брой използвани регистри, nfx = неясно! 8 0000 12C00000 05000040 00000000 B0000000 disp %ctpr1,L1 } ! Подготви прехода към началото на цикъла 9 { return %ctpr3 ! и връщането към извикващата функция 10 ord 0,-1,%r2 ! Задай начална стойност -1 на 65-битовия 11 0010 2340000C 82D4C005 83D4C005 000000F0 00000000 0000FFFF ord 0,-1,%r3 } ! умалител 12 0028 01000004 82C28211 L1: addd %r2,2,%r2 ! Получи следващото нечетно число - в младшата 13 0030 01010004 20C28221 cmpbdb %r2,2,%pred0 ! (получи преноса) 14 { addd %r3,1,%r3 ? %pred0! и в старшата дума 15 cmpbdb %r0,%r2,%pred1 ! Получи заема за младшите думи 16 0038 2300011C 83C18311 21828021 80828013 00000000 00006004 subd %r0,%r2,%r0 } ! Извади ги 17 { merged 0,1,%r4,%pred1 ! Запази заема " " " " 18 0050 1200010C 84C1C00F 20838121 00006184 cmpbdb %r1,%r3,%pred0 }! Ще има ли заем за старшите думи? 19 0060 11000104 81838113 00000000 0000E004 subd %r1,%r3,%r1 ? ~%pred0 ! Не, извади ги и провери дали може да 20 0070 11010104 20848121 00000000 0000E004 cmpbdb %r1,%r4,%pred0 ? ~%pred0! се извади и заемът за младшите думи 21 { subd %r1,%r4,%r1 ? ~%pred0 ! Ако може, го извади 22 0080 12100104 600400C0 81848113 0000E004 ct %ctpr1 ? ~%pred0 } ! и продължи цикъла 23 0090 01000004 82C1821B shrd %r2,1,%r2 ! Раздели получения умалител на 2 и копирай бит 24 { insfd %r3,63 << 6 | 1,%r2,%r0 ! 0 на r3 в бит 63 на r2, получавайки в 25 0098 22101004 200C00C0 80D4836D 0000820B 00000000 0000C10F ct %ctpr3 } ! r0 броя извадени последователни нечетни числа S/390x LISTING lcmult.s page 1 1 # Върни в регистър 2 най-малкото общо кратно (НОК) на числата в регисри 2 и 3 2 3 .global lcmult 4 lcmult: 5 0000 B904001E LGR 1,14 # Съхрани адреса на връщане, защото BRAS ще го промени! 6 0004 B9040052 LGR 5,2 7 0008 B9860043 MLGR 4,3 # 4:5 = A * B 8 000c A7E50007 BRAS 14,GCD # намери НОД(A, B) 9 0010 B9870042 DLGR 4,2 # регистър 5 = A * B / НОД(A, B) = НОК 10 0014 B9040025 LGR 2,5 # НОК трябва да се върне в регистър 2 11 0018 07F1 BR 1 # Върни се в извикващата програма 12 GCD: 13 .include "gcdivis.s" 1 # Върни в регистър 2 най-големия общ делител на числата в регистри 2 и 3 2 # (алгоритъм - Евклид от Александрия). 3 4 001a B9040002 LGR 0,2 5 001e B9810003 OGR 0,3 #unsigned gcd(unsigned a, unsigned b) 6 0022 A7740004 JNZ L1 #{ 7 0026 A7290001 LGHI 2,1 #____ if (a == 0 && b == 0) 8 002a B9020033 L1: LTGR 3,3 # \__ return 1; 9 002e 078E BER 14 #___ if (b == 0) 10 0030 B9020022 LTGR 2,2 #__ \___ return a; 11 0034 A7740004 JNE L2 # \ 12 0038 B9040023 LGR 2,3 # \__ if (a != 0) 13 003c B9210023 L2: CLGR 2,3 # while (a != b) 14 0040 A7B40006 JNL L3 # if (a < b) 15 0044 B90B0032 SLGR 3,2 # b -= a; 16 0048 A7F4FFFA J L2 # else 17 004c 078E L3: BER 14 # a -= b; 18 004e B90B0023 SLGR 2,3 # return b; 19 0052 A7F4FFF5 J L2 #} AMD64 GAS lcmult.s page 1 1 # Върни в RAX най-малкото общо кратно (НОК) на числата в RDI и RSI 2 3 .intel_syntax noprefix 4 .global lcmult 5 lcmult: 6 0000 4889F8 MOV RAX,RDI # съхрани числото A 7 0003 48F7E6 MUL RSI # RDX:RAX = A * B 8 0006 E8040000 00 CALL GCD # RDI = НОД(A, B) 9 000b 48F7F7 DIV RDI # RAX = A * B / НОД(A, B) = НОК 10 000e C3 RET # (при деленето е възможно препълване, нищо че НОД > 0) 11 GCD: 12 .include "gcdivis.s" 1 # Върни в RDI най-големия общ делител на числата в RDI и RSI 2 # (алгоритъм - Евклид от Александрия, реализация: Paul Hsieh). 3 4 000f 48F7DF NEG RDI # unsigned gcd(unsigned a, unsigned b) 5 0012 740D JE L3 # { 6 0014 48F7DF L1: NEG RDI # if (a == 0 && b == 0) return 1; 7 0017 4887F7 XCHG RDI,RSI #\ if (b == 0) return a; 8 001a 4829F7 L2: SUB RDI,RSI # \ if (a != 0) 9 001d 77FB JA L2 # \_ while (a != b) 10 001f 72F3 JB L1 # if (a < b) 11 0021 4801F7 L3: ADD RDI,RSI #\ b -= a; 12 0024 7503 JNE L4 # \_ else a -= b; 13 0026 48FFC7 INC RDI # return b; 14 0029 C3 L4: RET # } AARCH64 GAS lcmult.s page 1 1 // Върни в X0 най-малкото общо кратно (НОК) на числата в X0 и X1 2 // (произведението им трябва да е до 64 бита поради ограничението на 3 // командата UDIV; ARMv7 няма команда за делене с 128-битово делимо). 4 5 .global lcmult 6 lcmult: 7 0000 E4031EAA MOV X4,LR // Съхрани LR, защото BL ще го промени! 8 0004 227C009B MUL X2,X1,X0// X2 = A * B (няма смисъл от UMULH, защото няма UDIVL) 9 0008 03000094 BL GCD // намери НОД(A, B) 10 000c 4008C09A UDIV X0,X2,X0// X0 = A * B / НОД(A, B) = НОК 11 0010 80001FD6 BR X4 // Върни се в извикващата програма 12 GCD: 13 .include "gcdivis.s" 1 # Върни в X0 най-големия общ делител на числата в X0 и X1 2 # (алгоритъм - Евклид от Александрия). 3 4 0014 030001AA ORR X3,X0,X1 //unsigned gcd(unsigned a, unsigned b) 5 0018 430000B5 CBNZ X3,L1 //{ 6 001c 200080D2 MOV X0,#1 //___ if (a == 0 && b == 0) 7 0020 410000B5 L1: CBNZ X1,L3 // \__ return 1; 8 0024 C0035FD6 L2: RET //___ if (b == 0) 9 0028 400000B5 L3: CBNZ X0,L4 //__ \__ return a; 10 002c E00301AA MOV X0,X1 // \__ if (a != 0) 11 0030 1F0001EB L4: CMP X0,X1 // while (a != b) 12 0034 62000054 BHS L5 // if (a < b) 13 0038 210000CB SUB X1,X1,X0 // b -= a; 14 003c FDFFFF17 B L4 // else 15 0040 20FFFF54 L5: BEQ L2 // a -= b; 16 0044 000001CB SUB X0,X0,X1 // return b; 17 0048 FAFFFF17 B L4 //} ARC GAS lcmult.s page 1 1 # Върни в r0 най-малкото общо кратно (НОК) на числата в r0 и r1 2 # (произведението им трябва да е до 64 бита поради ограничението на 3 # командата DIVU; ARCv3 няма команда за делене със 128-битово делимо. 4 5 .global lcmult 6 lcmult: 7 0000 E743 MOVL_S r3,blink # Съхрани blink, защото BL_S ще го промени! 8 0002 3059 0200 MPYL r2,r1,r0 # r2 = A * B (няма смисъл от MPYDU, защото няма DIVDU) 9 0006 03F8 BL_S GCD # намери НОД(A, B) 10 0008 255A 0000 DIVUL r0,r2,r0 # r0 = A * B / НОД(A, B) = НОК 11 000c 2020 C000 J [r3] # Върни се в извикващата програма 12 GCD: 13 .include "gcdivis.s" 1 # Върни в r0 най-големия общ делител на числата в r0 и r1 2 # (алгоритъм - Евклид от Александрия). 3 4 0010 0558 7E80 ORL.F 0,r0,r1 #unsigned gcd(unsigned a, unsigned b) 5 0014 CA58 6100 MOVL.Z r0,1 #{ if (a == 0 && b == 0) return 1; 6 0018 0CE9 BREQL_S r1,0,L2 # if (b == 0) return a; 7 001a 4D58 0080 RCMPL r0,0 # if (a != 0) 8 001e CA58 4100 MOVL.EQ r0,r1 # ___ while (a != b) 9 0022 0D59 0080 L1: RCMPL r1,r0 #___/ if (a < b) 10 0026 C259 0500 SUBL.LO r1,r1,r0 # b -= a; 11 002a C258 4D00 SUBL.HI r0,r0,r1 # else a -= b; 12 002e FBF5 BNE_S L1 # return b; 13 0030 E07E L2: J_S [blink] #} PPC LISTING lcmult.s page 1 1 # Върни в r3 най-малкото общо кратно (НОК) на числата в r3 и r4 2 # (произведението им трябва да е до 64 бита поради ограничението на 3 # командата divwu; PowerPC64 няма команда за делене със 128-битово делимо). 4 5 .global lcmult 6 lcmult: 7 0000 7CE802A6 mflr r7 # Съхрани lr, защото bl ще го промени! 8 0004 7CA419D2 mulld r5,r4,r3# r5 = A * B 9 0008 48000011 bl GCD # намери НОД(A, B) 10 000c 7C651B92 divdu r3,r5,r3# r3 = A * B / НОД(A, B) = НОК 11 0010 7CE803A6 mtlr r7 12 0014 4E800020 blr # Върни се в извикващата програма 13 GCD: 14 .include "gcdivis.s" 1 # Върни в r3 най-големия общ делител на числата в r3 и r4 2 # (алгоритъм - Евклид от Александрия). 3 4 0018 7C662379 or. r6,r3,r4 #unsigned gcd(unsigned a, unsigned b) 5 001c 40820008 bne L1 #{ 6 0020 38600001 li r3,1 #____ if (a == 0 && b == 0) 7 0024 28240000 L1: cmpldi r4,0 # \__ return 1; 8 0028 4D820020 beqlr #___ if (b == 0) 9 002c 28230000 cmpldi r3,0 #__ \___ return a; 10 0030 40820008 bne L2 # \ 11 0034 7C832378 mr r3,r4 # \__ if (a != 0) 12 0038 7C232040 L2: cmpld r3,r4 # while (a != b) 13 003c 4080000C bge L3 # if (a < b) 14 0040 7C832050 subf r4,r3,r4 # b -= a; 15 0044 4BFFFFF4 b L2 # else 16 0048 4D820020 L3: beqlr # a -= b; 17 004c 7C641850 subf r3,r4,r3 # return b; 18 0050 4BFFFFE8 b L2 #} SPARC GAS lcmult.S page 1 1 ! Върни в %o0 най-малкото общо кратно (НОК) на числата в %o0 и %o1 2 ! (произведението им трябва да е до 64 бита поради ограничението на 3 ! командата „udivx“; SPARC64 няма команда за делене със 128-битово делимо). 4 5 .global lcmult 6 lcmult: 7 0000 9810000F mov %o7,%o4 ! Съхрани %o7, защото „call“ ще го промени! 8 0004 40000004 call GCD ! намери НОД(A, B) 9 0008 964A0009 mulx %o0,%o1,%o3 ! %o3 = A * B (изпълнява се преди „call“!) 10 000c 81C32008 jmpl %o4+8,%g0 ! Върни се в извикващата програма 11 0010 906AC008 udivx %o3,%o0,%o0 ! %o0 = A * B / НОД(A, B) = НОК (преди „jmpl“!) 12 GCD: 13 #include "gcdivis.s" SPARC GAS gcdivis.s page 1 1 ! Върни в %o0 най-големия общ делител на числата в %o0 и %o1 2 ! (алгоритъм - Евклид от Александрия, реализация за x86: Paul Hsieh). 3 4 0000 90A00008 subcc %g0,%o0,%o0!negcc!unsigned gcd(unsigned a, unsigned b) 5 0004 02680009 be %xcc,L3 ! { if (a == 0 && b == 0) return 1; 6 0008 94200008 L1: sub %g0,%o0,%o2!neg ___ 7 000c 90100009 mov %o1,%o0 !размени /*\*/ 8 0010 9210000A mov %o2,%o1 !%o0,%o1 \ if (b == 0) return a; 9 0014 90A20009 L2: subcc %o0,%o1,%o0 ! \ if (a != 0) 10 0018 186FFFFF bgu %xcc,L2 ! \_ while (a != b) 11 001c 01000000 nop ! / 12 0020 0A6FFFFA bcs %xcc,L1 !_ / if (a < b) 13 0024 01000000 nop ! \ / 14 0028 90820009 L3: addcc %o0,%o1,%o0 ! X b -= a; 15 002c 12680003 bne %xcc,L4 !_/ \_ else a -= b; 16 0030 01000000 nop 17 0034 90022001 inc %o0 ! return b; 18 0038 81C3E008 L4: retl ! } 19 003c 01000000 nop MIPS LISTING lcmult.s page 1 1 # Върни в $2 най-малкото общо кратно (НОК) на числата в $4 и $5 2 # (произведението им трябва да е до 64 бита поради ограничението на 3 # командата DIVU; MIPS64 няма команда за делене със 128-битово делимо). 4 5 .ent lcmult 6 .global lcmult 7 lcmult: 8 0000 03E03025 MOVE $6,$31 # Съхрани $31, защото BAL ще го промени! 9 0004 0085001D DMULTU $4,$5 10 MFLO $7 # $7 = A * B 11 0008 04110006 00003812 BAL GCD # намери НОД(A, B) 12 0010 14800002 00E4001F 0007000D DDIVU $2,$7,$4# LO = A * B / НОД(A, B) = НОК 13 001c 00C00008 00001012 JR $6 # Върни се в извикващата програма 14 GCD: 15 .include "gcdivis.s" 1 # Върни в $4 най-големия общ делител на числата в $4 и $5 2 # (алгоритъм - Евклид от Александрия). 3 4 0024 00851025 OR $2,$4,$5 #unsigned gcd(unsigned a, unsigned b) 5 0028 14400002 00000000 BNE $2,$0,L1 #{ 6 0030 24040001 LI $4,1 # if (a == 0 && b == 0) return 1; 7 0034 14A00003 00000000 L1: BNE $5,$0,L3 # if (b == 0) 8 003c 03E00008 00000000 L2: JR $31 # return a; 9 0044 00A4200A L3: MOVZ $4,$5,$4 # if (a != 0) 10 0048 0085082B 10200003 00000000 L4: BGEU $4,$5,L5 # while (a != b) 11 DSUBU $5,$5,$4 # if (a < b) 12 0054 1000FFFC 00A4282F B L4 # b -= a; 13 005c 1085FFF7 00000000 L5: BEQ $4,$5,L2 # else 14 DSUBU $4,$4,$5 # a -= b; 15 0064 1000FFF8 0085202F B L4 # return b; } 16 006c 00000000 .end lcmult RISC-V LISTING lcmult.s page 1 1 # Върни в a0 най-малкото общо кратно (НОК) на числата в a0 и a1 2 # (произведението им трябва да е до 64 бита поради ограничението на 3 # командата DIVU; RV64 няма команда за делене със 128-битово делимо). 4 5 .global lcmult 6 lcmult: 7 0000 13860000 MV a2,ra # Съхрани ra, защото JAL ще го промени! 8 0004 B306B502 MUL a3,a0,a1 # a3 = A * B 9 0008 EF00C000 JAL ra,GCD # намери НОД(A, B) 10 000c 33D5A602 DIVU a0,a3,a0 # aO = A * B / НОД(A, B) = НОК 11 0010 67000600 JR a2 # Върни се в извикващата програма 12 GCD: 13 .include "gcdivis.s" 1 # Върни в a0 най-големия общ делител на числата в a0 и a1 2 # (алгоритъм - Евклид от Александрия). 3 4 0014 3367B500 OR a4,a0,a1 #unsigned gcd(unsigned a, unsigned b) 5 0018 63140700 BNE a4,x0,L1 #{ 6 001c 13051000 LI a0,1 # if (a == 0 && b == 0) return 1; 7 0020 63940500 L1: BNEZ a1,L3 # if (b == 0) 8 0024 67800000 L2: RET # return a; 9 0028 63140500 L3: BNEZ a0,L4 # if (a != 0) 10 002c 13850500 MV a0,a1 11 0030 6376B500 L4: BGEU a0,a1,L5 # while (a != b) 12 0034 B385A540 SUB a1,a1,a0 # if (a < b) 13 0038 6FF09FFF J L4 # b -= a; 14 003c E304B5FE L5: BEQ a0,a1,L2 # else 15 0040 3305B540 SUB a0,a0,a1 # a -= b; 16 0044 6FF0DFFE J L4 # return b; } LOONGARCH64 GAS lcmult.s page 1 1 # Върни в регистър r4 най-малкото общо кратно (НОК) на числата в регистри 2 # r4 и r5 (произведението им трябва да е до 64 бита поради ограничението на 3 # командата DIV.DU; LoongArch64 няма команда за делене със 128-битово делимо). 4 5 .global lcmult 6 lcmult: 7 0000 28001500 MOVE $r8,$r1 # Съхрани r1, защото BL ще го промени! 8 0004 87941D00 MUL.D $r7,$r4,$r5 # r7 = A * B 9 0008 000C0054 BL GCD # намери НОД(A, B) 10 000c E4102300 DIV.DU $r4,$r7,$r4 # r4 = A * B / НОД(A, B) = НОК 11 0010 0001004C JIRL $r0,$r8,0 # Върни се в извикващата програма 12 GCD: 13 .include "gcdivis.s" 1 # Върни в r4 най-големия общ делител на числата в r4 и r5 2 # (алгоритъм - Евклид от Александрия). 3 4 0014 86141500 OR $r6,$r4,$r5 #unsigned gcd(unsigned a, unsigned b) 5 0018 C0080044 BNEZ $r6,L1 #{ 6 001c 04048003 ORI $r4,$r0,1 # if (a == 0 && b == 0) return 1; 7 0020 A0080044 L1: BNEZ $r5,L3 # if (b == 0) 8 0024 2000004C L2: JIRL $r0,$r1,0 # return a; 9 0028 80080044 L3: BNEZ $r4,L4 # if (a != 0) 10 002c A4001500 OR $r4,$r5,$r0 11 0030 850C006C L4: BGEU $r4,$r5,L5 # while (a != b) 12 0034 A5901100 SUB.D $r5,$r5,$r4 # if (a < b) 13 0038 FFFBFF53 B L4 # b -= a; 14 003c 85E8FF5B L5: BEQ $r4,$r5,L2 # else 15 0040 84941100 SUB.D $r4,$r4,$r5 # a -= b; 16 0044 FFEFFF53 B L4 # return b; } # Върни в регистър $0 най-малкото общо кратно (НОК) на числата в lcmult.o: file format ecoff-littlealpha # регистри $16 и $17. Disassembly of section .text: .ent lcmult .globl lcmult 0000000000000000 : lcmult: 0: 06 04 11 4e mulq a0,a1,t5 bis $31,$26,$5 # Съхрани $26, защото „bsr“ ще го промени! 4: 05 04 fa 47 mov ra,t4 mulq $16,$17,$6 8: 07 06 11 4e umulh a0,a1,t6 umulh $16,$17,$7 # $7:$6 = A * B c: 07 00 40 d3 bsr ra,2c bsr $26,GCD # Намери НОД(A, B) 10: 12 04 f0 47 mov a0,a2 bis $31,$16,$18 # Делител 14: 10 04 e6 47 mov t5,a0 bis $31,$6,$16 # Младша дума на делимото 18: 11 04 e7 47 mov t6,a1 bis $31,$7,$17 # Старша дума на делимото 1c: 13 04 ff 47 clr a3 bis $31,$31,$19 # Адрес на остатъка NULL, за да не се съхранява 20: 00 00 40 d3 bsr ra,24 bsr $26,udiv128 # $0 = A * B / НОД(A, B) = НОК 24: 1a 04 e5 47 mov t4,ra bis $31,$5,$26 # Възстанови адреса на връщане 28: 01 80 fa 6b ret zero,(ra),0x1 ret # Върни се в извикващата програма GCD: #include "gcdivis.s" # Върни в $16 най-големия общ делител на числата в $16 и $17 # (алгоритъм - Евклид от Александрия). 2c: 02 04 11 46 or a0,a1,t1 bis $16,$17,$2 #unsigned gcd(unsigned a, unsigned b) 30: 01 00 40 f4 bne t1,38 bne $2,L1 #{ 34: 01 00 1f 22 lda a0,1(zero) lda $16,1($31) # if (a == 0 && b == 0) return 1; 38: 01 00 20 f6 bne a1,40 L1: bne $17,L3 # if (b == 0) 3c: 01 80 fa 6b ret zero,(ra),0x1 L2: ret # return a; 40: 90 04 11 46 cmoveq a0,a1,a0 L3: cmoveq $16,$17,$16 # if (a != 0) 44: a2 07 30 42 cmpule a1,a0,t1 L4: cmpule $17,$16,$2 # while (a != b) 48: 02 00 40 f4 bne t1,54 bne $2,L5 # 4c: 31 05 30 42 subq a1,a0,a1 subq $17,$16,$17 # if (a < b) 50: fc ff ff c3 br 44 br $31,L4 # b -= a; 54: a2 05 11 42 cmpeq a0,a1,t1 L5: cmpeq $16,$17,$2 # else 58: f8 ff 5f f4 bne t1,3c bne $2,L2 # 5c: 30 05 11 42 subq a0,a1,a0 subq $16,$17,$16 # a -= b; 60: f8 ff ff c3 br 44 br $31,L4 # return b; } 64: 1f 04 ff 47 nop .end lcmult 68: 00 00 fe 2f unop 6c: 1f 04 ff 47 nop GAS for MMIX lcmult.s page 1 1 % Върни в регистър $0 най-малкото общо кратно (НОК) на числата в 2 % регистри $0 и $1. 3 4 .global lcmult 5 lcmult: 6 0000 1A040001 MULU $4,$0,$1 % rH:$4 = A * B 7 0004 FE030003 GET $3,rH 8 0008 F6010003 PUT rD,$3 % rD:$4 = A * B 9 000c F4030002 GETA $3,@+8 10 0010 F0000005 JMP GCD % $0 = НОД(A, B) 11 0014 1E000400 DIVU $0,$4,$0 % $0 = A * B / НОД(A, B) = НОК 12 0018 C6020202 XOR $2,$2,$2 % Нулирай старшата дума на делимото, защото 13 001c F6010002 PUT rD,$2 % кодът, генериран от компилатора, очаква там 0 14 0020 F8010000 POP 1,0 % Върни се в извикващата програма 15 GCD: 16 .include "gcdivis.s" 1 % Върни в $0 най-големия общ делител на числата в $0 и $1. 2 % ВНИМАНИЕ: Адресът на връщане е подаден в регистър $3, а не в обичайния rJ! 3 % Алгоритъм - Евклид от Александрия. 4 5 0024 C0020001 OR $2,$0,$1 %unsigned gcd(unsigned a, unsigned b) 6 0028 4A020002 BNZ $2,L1 %{ 7 002c E3000001 SETL $0,1 % if (a == 0 && b == 0) return 1; 8 0030 4A010002 L1: BNZ $1,L3 % if (b == 0) 9 0034 9F030300 L2: GO $3,$3,0 % return a; 10 0038 62000001 L3: CSZ $0,$0,$1 % if (a != 0) 11 003c 32020001 L4: CMPU $2,$0,$1 % while (a != b) 12 0040 48020003 BNN $2,L5 % 13 0044 26010100 SUBU $1,$1,$0 % if (a < b) 14 0048 F1FFFFFD JMP L4 % b -= a; 15 004c 4302FFFA L5: BZ $2,L2 % else 16 0050 26000001 SUBU $0,$0,$1 % a -= b; 17 0054 F1FFFFFA JMP L4 % return b; } HPPA64 LISTING lcmult.s page 1 1 ; Върни в %R28 най-малкото общо кратно (НОК) на числата в регистри %R26 и %R25 2 3 .global lcmult 4 lcmult: 5 0000 0FD912F0 STD,MA %R25,8(%SP) ; Връзка между целочислените регистри и тези за 6 0004 E8200000 B,L UM64X64,%R1 ; числа с плаваща запетая има само през паметта 7 0008 0FDA12F0 STD,MA %R26,8(%SP) ; R28:R29 = A * B; изпълнява се преди „B,L“! 8 000c E8200020 B,L GCD,%R1 ; R26 = НОД(A, B); изпълнява се след „COPY“! 9 0010 08000257 COPY %R0,%R23 ; Адрес на остатъка NULL, за да не се съхранява 10 0014 081A0258 COPY %R26,%R24 ; Делител 11 0018 081C025A COPY %R28,%R26 ; Старша дума на делимото 12 001c 081D0259 COPY %R29,%R25 ; Младша дума на делимото 13 0020 E8000002 B,N udiv128 ; Ще върне в R28 = A * B / НОД(A, B) = НОК 14 GCD: 15 .include "gcdivis.s" 1 ; Върни в %R26 най-големия общ делител на числата в %R26 и %R25 2 ; (алгоритъм - Евклид от Александрия). 3 4 0024 0B593260 OR,*<> %R25,%R26,%R0 ;unsigned gcd(unsigned a, unsigned b) 5 0028 341A0002 LDI 1,%R26 ;{ 6 002c 0B393260 OR,*<> %R25,%R25,%R0 ; if (a == 0 && b == 0) return 1; 7 0030 E820D002 L1: BVE,N (%R1) ; if (b == 0) 8 0034 0B5A3260 OR,*<> %R26,%R26,%R0 ; return a; 9 0038 0819025A COPY %R25,%R26 ; if (a != 0) 10 003c 0B593420 L2: SUB,*<> %R25,%R26,%R0 ; while (a != b) 11 0040 E81F1FD7 B,N L1 12 0044 0B59A420 SUB,*<<= %R25,%R26,%R0 ; if (a < b) 13 0048 0B590419 SUB %R25,%R26,%R25 ; b -= a; 14 004c 0B3AA420 SUB,*<<= %R26,%R25,%R0 ; else 15 0050 0B3A041A SUB %R26,%R25,%R26 ; a -= b; 16 0054 E81F1FC7 B,N L2 ; return b; } UNDEFINED SYMBOLS UM64X64 udiv128 TILE-Gx GAS lcmult.s page 1 1 # Върни в регистър r0 най-малкото общо кратно (НОК) на числата в регистри r0 и 2 # r1 (всяко от тях до 32 бита поради ограничението на командата „MUL_LU_LU“). 3 4 .global lcmult 5 lcmult: 6 { MOVE r9,lr # Съхрани lr, защото „JAL“ ще го промени! 7 0000 0810F8D0 E4FE3B28 MUL_LU_LU r8,r0,r1 } # r8 = A * B 8 0008 003048D1 02000020 JAL GCD # Намери НОД(A, B) 9 0010 00304851 01F83B28 MOVE r2,r0 # Делител 10 { MOVE r0,r8 # Младша дума на делимото 11 0018 00F207D1 E0FF3B28 MOVE r1,zero } # Старша дума на делимото 12 { MOVE r3,zero # Адрес на остатъка NULL, за да не се съхранява 13 0020 C3FF0751 00000020 JAL udiv128 } # r0 = A * B / НОД(A, B) = НОК 14 0028 00304851 20716A28 JR r9 # Върни се в извикващата програма 15 GCD: 16 .include "gcdivis.s" 1 # Върни в r0 най-големия общ делител на числата в r0 и r1 2 # (алгоритъм - Евклид от Александрия). 3 4 0030 00304851 01083A28 OR r2,r0,r1 #unsigned gcd(unsigned a, unsigned b) 5 0038 00304851 41008017 BNEZT r2,L1 #{ 6 0040 00304851 E00F0818 MOVEI r0,1 # if (a == 0 && b == 0) return 1; 7 0048 00304851 21008017 L1: BNEZT r1,L3 # if (b == 0) 8 0050 00304851 E0766A28 L2: JR lr # return a; 9 0058 00101450 00306A28 L3: CMOVEQZ r0,r0,r1 # if (a != 0) 10 0060 00304851 21001228 L4: CMPLEU r2,r1,r0 # while (a != b) 11 0068 00304851 4100C017 BNEZ r2,L5 # 12 { SUB r1,r1,r0 # if (a < b) 13 0070 41004451 FFFFFF27 J L4 } # b -= a; 14 0078 00304851 01080A28 L5: CMPEQ r2,r0,r1 # else 15 0080 00304851 5DF8FF17 BNEZ r2,L2 # 16 { SUB r0,r0,r1 # a -= b; 17 0088 001044D1 FDFFFF27 J L4 } # return b; } UNDEFINED SYMBOLS udiv128 IA-64 GAS lcmult.s page 1 1 // Върни в регистър r8 най-малкото общо кратно (НОК) на числата в 2 // регистри in0 и in1. 3 4 .global lcmult 5 lcmult: 6 ALLOC loc0=ar.pfs,2,2,4,0 7 MOV loc1=rp // Съхрани rp, защото „BR.CALL“ ще го промени! 8 SETF.SIG f6=in0 9 0000 00102108 80053002 00620000 00000400 SETF.SIG f7=in1 // Подготви множителите 10 XMPY.LU f8=f6,f7 11 0010 0F308000 E1187008 01C23100 00000400 XMPY.HU f9=f6,f7 // f9:f8 = A * B 12 MOV out0=in0 // Копирай аргументите 13 0020 0C000000 01008000 180E7400 00000400 MOV out1=in1 14 0030 0C000000 01009000 180E7680 04000184 BR.CALL.SPTK rp=GCD // r8 = НОД(A, B) 15 GETF.SIG out0=f8 // Младша дума на произведението и на делимото 16 0040 10280142 00210000 00020000 50000050 GETF.SIG out1=f9 // Старша " " " " " " " " " 17 MOV out2=r8 // Делител (НОД) 18 0050 08202100 E110504A 00C221C0 04400084 MOV out3=r0 // Адрес на остатъка NULL, за да не се запазва 19 BR.CALL.SPTK rp=udiv128 // r8 = A * B / НОД(A, B) = НОК 20 MOV rp=loc1 // Възстанови адреса на връщане и състоянието 21 0060 10380100 00210000 00020000 00000050 MOV ar.pfs=loc0 // на предишната функция, защото сме извикали 22 BR.RET.SPTK rp // подпрограма. Върни се в извикващата функция 23 GCD: 24 .include "gcdivis.s" 1 // Върни в r8 най-големия общ делител на числата в in0 и in1. 2 // Алгоритъм - Евклид от Александрия. 3 4 0070 00000000 01000018 05800300 2002AA00 ALLOC loc1=ar.pfs,2,2,0,0 5 OR loc0=in0,in1 //unsigned gcd(unsigned a, unsigned b) 6 0080 11000000 01000000 00020080 00008400 CMP.EQ p6,p7=loc0,r0 //{ 7 0090 03181108 80052002 851C40C0 20021CE0 (p6) ADD r8=r0,r0,1 // if (a == 0 && b == 0) 8 (p6) BR.RET.SPTK rp // return 1; 9 CMP.EQ p6,p7=in1,r0 // if (b == 0) 10 00a0 D0400000 01200000 00020083 00008400 (p6) MOV r8=in0 // return a; 11 (p6) BR.RET.SPTK rp 12 00b0 0A308400 07B88100 80004200 00000400 CMP.EQ p6,p7=in0,r0 // if (a != 0) 13 L1:(p7) CMP.EQ p6,p7=in0,in1 // while (a != b) 14 00c0 10000000 01000000 00020083 00008400 (p6) MOV r8=in1 15 00d0 01308000 07380000 00020000 00000400 (p6) BR.RET.SPTK rp 16 00e0 EA308042 07B88100 84004200 00000400 CMP.LTU p8,p9=in0,in1 // if (a < b) 17 (p8) SUB in1=in1,in0 // b -= a; 18 00f0 10000000 01000000 00020083 00008400 (p9) SUB in0=in0,in1 // else a -= b; 19 0100 0A408042 0934120A 810AC004 040A1580 BR L1 // return b; } UNDEFINED SYMBOLS udiv128 E2K GAS lcmult.S page 1 1 ! Върни в регистър r0 най-малкото общо кратно (НОК) на числата в регистри r0 и 2 ! r1 (произведението им трябва да е до 64 бита поради ограничение на командата 3 ! UDIVD – „Эльбрус-2000“ няма команда за делене със 128-битово делимо; освен 4 ! това командата за делене дава 32-битово, а не 64-битово частно, затова и 5 ! числата трябва да са такива, че НОК да им бъде 32-бита). 6 7 .global lcmult 8 lcmult: 9 { setwd wsz=8,nfx=1 ! wsz = размер на прозореца с GCD, nfx = неясно 10 disp %ctpr1,GCD ! Подготви извикването на функцията за НОД 11 ord %r0,0,%b[0] ! Предай аргументите на извикваната функция 12 0000 24C0000C 00C08005 01C08105 09000040 00000000 10010000 ord %r1,0,%b[1] } 13 { call %ctpr1,wbs=4 ! Функцията връща НОД(A, B) в b[0] (r0 за нея) 14 0018 23901004 200400C0 80818021 04000050 0000C001 00000000 muld %r0,%r1,%r0 } ! A * B (няма смисъл от UMULHD – вж по-горе) 15 { udivd %r0,%b[0],%r0 ! r0 = A * B / НОД(A, B) = НОК 16 0030 12400080 80008041 000000F0 00000000 return %ctpr3 } ! Подготви връщането към извикващата функция 17 0040 01100000 200C00C0 ct %ctpr3 ! и ѝ върни управлението 18 GCD: 19 #include "gcdivis.s" E2K GAS gcdivis.s page 1 1 ! Върни в r0 най-големия общ делител на числата в r0 и r1. 2 ! Алгоритъм - Евклид от Александрия. 3 4 0000 01400000 09000040 disp %ctpr1,L1 ! Подготви прехода към началото на цикъла 5 { return %ctpr3 ! и връщането към извикващата функция 6 0008 12400004 82818005 000000F0 00000000 ord %r0,%r1,%r2 } !unsigned gcd(unsigned a, unsigned b) 7 0018 01010004 40C08221 cmpedb %r2,0,%pred0 !{ 8 { ord 0,1,%r0 ? %pred0 ! if (a == 0 && b == 0) 9 ct %ctpr3 ? %pred0 ! return 1; 10 0020 2310010C 400C00C0 80C1C005 40C08121 00000000 00006004 cmpedb %r1,0,%pred0 } ! if (b == 0) 11 { ct %ctpr3 ? %pred0 ! return a; 12 0038 12100004 400C00C0 40C08021 00000000 cmpedb %r0,0,%pred0 } ! if (a != 0) 13 0048 11010104 40818021 00000000 0000E004 L1: cmpedb %r0,%r1,%pred0 ? ~%pred0! while (a != b) 14 { ord %r1,0,%r0 ? %pred0 15 ct %ctpr3 ? %pred0 16 0058 2310010C 400C00C0 80C08105 21818021 00000000 00006004 cmpbdb %r0,%r1,%pred1 } ! if (a < b) 17 { subd %r1,%r0,%r1 ? %pred1 ! b -= a; 18 subd %r0,%r1,%r0 ? ~%pred1 ! else a -= b; 19 0070 2310010C 200400C0 81808113 80818013 00000000 0000610D ct %ctpr1 } ! return b; } S/390x LISTING nsamebit.s page 1 1 # Да се напише подпрограма, която да връща в регистър 2 броя на съвпадащите 2 # битове на една и съща позиция в думите, подадени в регистри 2, 3 и 4. 3 4 .global nsamebit 5 nsamebit: 6 0000 B9820032 XGR 3,2 # 3 ^= 2 (съвпадащите битове стават 0, другите —— 1) 7 0004 B9820042 XGR 4,2 # 4 ^= 2 ( " " " " " " " " " " ) 8 0008 B9664033 NOGRK 3,3,4 # 3 = ~(3 ^ 2 | 4 ^ 2) " " " 1, " " " 0) 9 000c B9E18023 POPCNT 2,3,0b1000# Тази команда изисква ниво на архитектурата ARCH(12) 10 0010 07FE0707 BR 14 # Рег.2 = брой лог. единици в рег. 3 (съвпадащи битове) AMD64 GAS nsamebit.s page 1 1 # Да се напише подпрограма, която да връща в регистър EAX броя на съвпадащите 2 # битове на една и съща позиция в думите, подадени в регистри RDI, RSI и RDX. 3 4 .intel_syntax noprefix 5 .global nsamebit 6 nsamebit: 7 0000 4831D7 XOR RDI,RDX # RDI ^= RDX (съвпадащите битове стават 0, другите – 1) 8 0003 4831D6 XOR RSI,RDX # RSI ^= RDX ( " " " " " " " " " " ) 9 0006 4809F7 OR RDI,RSI # RDI = RDI ^ RDX | RSI ^ RDX (" " " " " " ) 10 0009 48F7D7 NOT RDI # Направи съвпадащите битове лог. 1, а другите – лог. 0 11 000c F3480FB8 C7 POPCNT RAX,RDI # Преброй съвпадащите битове 12 0011 C3 RET # и върни броя им в EAX (RAX) AARCH64 GAS nsamebit.s page 1 1 // Да се напише подпрограма, която да връща в регистър X0 броя на съвпадащите 2 // битове на една и съща позиция в думите, подадени в регистри X0, X1 и X2. 3 4 .global nsamebit 5 nsamebit: 6 0000 210000CA EOR X1,X1,X0// X1 ^= X0 (съвпадащите битове стават 0, другите —— 1) 7 0004 420000CA EOR X2,X2,X0// X2 ^= X0 (" " " " " " " " " " ") 8 0008 210002AA ORR X1,X1,X2// X1 = X1 ^ X0 | X2 ^ X0 ( " " " " " " ") 9 000c E10321AA MVN X1,X1 // Направи съвпадащите битове лог. 1, несъвпадащите – 0 10 0010 E0031FAA MOV X0,XZR // Инициализирай брояча на лог. единици 11 0014 210001AB L1: ADDS X1,X1,X1// Изведи поредния бит в преноса 12 0018 00001F9A ADC X0,X0,XZR//Преброй поредния бит като съвпадащ, ако е лог. 1 13 001c C1FFFF54 BNE L1 // Повтаряй, докато има още останали лог. единици в X1 14 0020 C0035FD6 RET // X0 = брой лог. единици в X1 (т.е. съвпадащи битове) ARC GAS nsamebit.s page 1 1 # Да се напише подпрограма, която да връща в регистър r0 броя на съвпадащите 2 # битове на една и съща позиция в думите, подадени в регистри r0, r1 и r2. 3 4 .global nsamebit 5 nsamebit: 6 0000 0759 0100 XORL r1,r1,r0 # r1 ^= r0 (съвпадащите битове стават 0, другите —— 1) 7 0004 075A 0200 XORL r2,r2,r0 # r2 ^= r0 (" " " " " " " " " " ") 8 0008 5779 ORL_S r1,r1,r2 # r1 = r1 ^ r0 | r2 ^ r0 ( " " " " " " ") 9 000a 40D8 MOVL_S r0,64 # Инициализирай изваждащия брояч на лог. единици 10 000c 0059 4180 L1: ADDL.F r1,r1,r1 # Изведи поредния бит в преноса 11 0010 4358 0000 SBCL r0,r0,0 # Преброй поредния бит като несъвпадащ, ако е лог. 1 12 0014 FCF5 BNE_S L1 # Повтаряй, докато има още останали лог. единици в r1 13 0016 E07E J_S [blink] # r0 = брой лог. единици в r1 (т.е. съвпадащи битове) PPC LISTING nsamebit.s page 1 1 # Да се напише подпрограма, която да връща в регистър r3 броя на съвпадащите 2 # битове на една и съща позиция в думите, подадени в регистри r3, r4 и r5. 3 4 .global nsamebit 5 nsamebit: 6 0000 7C841A78 xor r4,r4,r3# r4 ^= r3 (съвпадащите битове стават 0, другите —— 1) 7 0004 7CA51A78 xor r5,r5,r3# r5 ^= r3 (" " " " " " " " " " ") 8 0008 7C8428F8 nor r4,r4,r5# r4 = ~(r4 ^ r3 | r5 ^ r3) " " " 1," " " 0) 9 000c 38600000 li r3,0 # Инициализирай брояча на лог. единици 10 0010 7C842015 L1: addc. r4,r4,r4# Изведи поредния бит в преноса 11 0014 7C630194 addze r3,r3 # Преброй поредния бит като съвпадащ, ако е лог. 1 12 0018 4082FFF8 bne L1 # Повтаряй, докато има още останали лог. единици в r4 13 001c 4E800020 blr # r3 = брой лог. единици в r4 (т.е. съвпадащи битове) SPARC GAS nsamebit.s page 1 1 ! Да се напише подпрограма, която да връща в регистър %o0 броя на съвпадащите 2 ! битове на една и съща позиция в думите, подадени в регистри %o0, %o1 и %o2. 3 4 .global nsamebit 5 nsamebit: 6 0000 921A0009 xor %o0,%o1,%o1!%o1 ^= %o0 (съвпадащите битове стават 0, другите 1) 7 0004 941A000A xor %o0,%o2,%o2!%o2 ^= %o0 (" " " " " " " " " " ) 8 0008 9212400A or %o1,%o2,%o1!%o1 = %o1 ^ %o0 | %o2 ^ %o0 ( " " " " " ) 9 000c 923A4000 not %o1 ! Направи съвпадащите битове лог. 1, несъвпадащите – 0 10 0010 81C3E008 retl ! Изпълнява се след „popc“! 11 0014 91700009 popc %o1,%o0 ! %o0 = брой лог. единици в %o1 (т.е. съвпадащи битове) MIPS LISTING nsamebit.s page 1 1 # Да се напише подпрограма, която да връща в регистър $2 броя на съвпадащите 2 # битове на една и съща позиция в думите, подадени в регистри $4, $5 и $6. 3 4 .ent nsamebit 5 .global nsamebit 6 nsamebit: 7 0000 00A42826 XOR $5,$5,$4# $5 ^= $4 (съвпадащите битове стават 0, другите —— 1) 8 0004 00C43026 XOR $6,$6,$4# $6 ^= $4 (" " " " " " " " " " ") 9 0008 00A62827 NOR $5,$5,$6# $5 = ~($5 ^ $4 | $6 ^ $4) " " " 1," " " 0) 10 000c 24020000 LI $2,0 # Инициализирай брояча на лог. единици 11 0010 00A0302A L1: SLT $6,$5,$0# Съхрани най-старшия бит, преди да изместиш останалите 12 0014 00052878 DSLL $5,$5,1 13 DADDU $2,$2,$6# Преброй поредния бит като съвпадащ, ако е бил лог. 1 14 0018 14A0FFFD 0046102D BNE $5,$0,L1# Повтаряй, докато има още останали лог. единици в $5 15 0020 03E00008 00000000 JR $31 # $2 = брой лог. единици в $5 (т.е. съвпадащи битове) 16 0028 00000000 00000000 .end nsamebit RISC-V LISTING nsamebit.s page 1 1 # Да се напише подпрограма, която да връща в регистър a0 броя на съвпадащите 2 # битове на една и съща позиция в думите, подадени в регистри a0, a1 и a2. 3 4 .global nsamebit 5 nsamebit: 6 0000 B3C5A500 XOR a1,a1,a0# a1 ^= a0 (съвпадащите битове стават 0, другите —— 1) 7 0004 3346A600 XOR a2,a2,a0# a2 ^= a0 (" " " " " " " " " " ") 8 0008 B3E5C500 OR a1,a1,a2 9 000c 93C5F5FF NOT a1,a1 # a1 = ~(a1 ^ a0 | a2 ^ a0) " " " 1," " " 0) 10 0010 13050000 MV a0,x0 # Инициализирай брояча на лог. единици 11 0014 33A60500 L1: SLT a2,a1,x0# Съхрани най-старшия бит, преди да изместиш останалите 12 0018 93951500 SLLI a1,a1,1 13 001c 3305C500 ADD a0,a0,a2# Преброй поредния бит като съвпадащ, ако е бил лог. 1 14 0020 E39A05FE BNEZ a1,L1 # Повтаряй, докато има още останали лог. единици в a1 15 0024 67800000 RET # a0 = брой лог. единици в a1 (т.е. съвпадащи битове) LOONGARCH64 GAS nsamebit.s page 1 1 # Да се напише подпрограма, която да връща в регистър r4 броя на съвпадащите 2 # битове на една и съща позиция в думите, подадени в регистри r4, r5 и r6. 3 4 .global nsamebit 5 nsamebit: 6 0000 A5901500 XOR $r5,$r5,$r4#r5 ^= r4 (съвпадащите битове стават 0, другите — 1) 7 0004 C6901500 XOR $r6,$r6,$r4#r6 ^= r4 ( " " " " " " " " " " ) 8 0008 A5181400 NOR $r5,$r5,$r6#r5 = ~(r5 ^ r4 | r6 ^ r4) " " 1, " " "0) 9 000c 04001500 OR $r4,$r0,$r0# Инициализирай брояча на лог. единици 10 0010 A6001200 L1: SLT $r6,$r5,$r0# Съхрани най-старшия бит, преди да изместиш другите 11 0014 A5044100 SLLI.D $r5,$r5,1 12 0018 84981000 ADD.D $r4,$r4,$r6#Преброй поредния бит като съвпадащ, ако е бил лог.1 13 001c BFF4FF47 BNEZ $r5,L1 # Повтаряй, докато има още останали лог. единици в r5 14 0020 2000004C JIRL $r0,$r1,0 # r4 = брой лог. единици в r5 (т.е. съвпадащи битове) # Да се напише подпрограма, която да връща в регистър $0 броя на съвпадащите nsamebit.o: file format ecoff-littlealpha # битове на една и съща позиция в думите, подадени в регистри $16, $17 и $18. Disassembly of section .text: .ent nsamebit .globl nsamebit 0000000000000000 : nsamebit: 0: 11 08 11 46 xor a0,a1,a1 xor $16,$17,$17# $17 ^= $16; съвпадащите битове стават 0, другите 1 4: 12 08 12 46 xor a0,a2,a2 xor $16,$18,$18# $18 ^= $16; " " " " " " " " " 8: 11 04 32 46 or a1,a2,a1 bis $17,$18,$17# $17 = ($17 ^ $16 | $18 ^ $16) " " " " " c: 11 05 f1 47 not a1,a1 ornot $31,$17,$17# Направи съвпадащите битове 1, а несъвпадащите – 0 10: 00 06 f1 73 ctpop a1,v0 ctpop $17,$0 # $0 = брой единици в $17 (т.е. съвпадащи битове) 14: 01 80 fa 6b ret zero,(ra),0x1 ret 18: 1f 04 ff 47 nop .end nsamebit 1c: 00 00 fe 2f unop GAS for MMIX nsamebit.s page 1 1 % Да се напише подпрограма, която да връща в регистър $0 броя на съвпадащите 2 % битове на една и съща позиция в думите, подадени в регистри $0, $1 и $2. 3 4 .global nsamebit 5 nsamebit: 6 0000 C6010100 XOR $1,$1,$0 % $1 ^= $0; съвпадащите битове стават 0, другите 1 7 0004 C6020200 XOR $2,$2,$0 % $2 ^= $0; " " " " " " " " " " 8 0008 C4010102 NOR $1,$1,$2 % $1 = ~($1 ^ $0 | $2 ^ $0) " " " " " " 9 000c DB000100 SADD $0,$1,0 % $0 = брой единици в $1 (т.е. съвпадащи битове) 10 0010 F8010000 POP 1,0 HPPA64 LISTING nsamebit.s page 1 1 ; Да се напише подпрограма, която да връща в регистър %R28 броя на съвпадащите 2 ; битове на една и съща позиция в думите, подадени в регистри %R26, %R25 и %R24 3 4 .global nsamebit 5 nsamebit: 6 0000 0B590299 XOR %R25,%R26,%R25 ; R25 ^= R26 (съвпадащите битове стават 0) 7 0004 0B580298 XOR %R24,%R26,%R24 ; R24 ^= R26 ( " " " " " " " ) 8 0008 0B190259 OR %R25,%R24,%R25 ; R25 = R25 ^ R26 | R24 ^ R26 (" " " ) 9 000c 0B200999 UADDCM %R0,%R25,%R25 ; Направи съвпадащите битове лог. 1 10 0010 341C0000 LDI 0,%R28 ; Инициализирай брояча на лог. единици 11 0014 0B390619 L1: ADD %R25,%R25,%R25 ; Изведи поредния бит в преноса 12 0018 BC193FED CMPB,*<> %R25,%R0,L1 ; Повтаряй,докато R25 ≠ 0 (изп.се след „ADD,DC“ 13 001c 081C073C ADD,DC %R28,%R0,%R28 ; Преброй поредния бит като съвпадащ, ако е 1 14 0020 E840D002 BVE,N (%R2) ; R28 = брой лог.единици, т.е. съвпадащи битове TILE-Gx GAS nsamebit.s page 1 1 # Да се напише подпрограма, която да връща в регистър r0 броя на съвпадащите 2 # битове на една и съща позиция в думите, подадени в регистри r0, r1 и r2. 3 4 .global nsamebit 5 nsamebit: 6 { XOR r1,r0,r1# r1 ^= r0; съвпадащите битове стават 0, другите – 1 7 0000 01108052 0110D628 XOR r2,r0,r2}#r2 ^= r0; " " " " " " " " " " 8 0008 003048D1 20103828 NOR r1,r1,r2# r1 = ~(r1 ^ r0 | r2 ^ r0) " " " 1 " " " 0 9 { PCNT r0,r1 # r0 = брой единици в r1 (т.е. съвпадащи битове) 10 0010 40604851 E0766A28 JR lr } IA-64 GAS nsamebit.s page 1 1 // Да се напише подпрограма, която да връща в регистър r8 броя на съвпадащите 2 // битове на една и съща позиция в думите, подадени в регистри in0, in1 и in2. 3 4 .global nsamebit 5 nsamebit: 6 ALLOC loc0=ar.pfs,3,1,0,0 7 XOR in1=in0,in1//in1 ^= in0; съвпадащите битове стават 0, другите 1 8 XOR in2=in0,in2//in2 ^= in0; " " " " " " " " " 9 0000 01181108 80051002 851E4040 04123D80 OR in1=in1,in2//in1 = (in1 ^ in0 | in2 ^ in0) " " " " " 10 XOR in1=-1,in1 // Направи съвпадащите битове 1, а несъвпадащите – 0 11 POPCNT r8=in1 // r8 = брой единици в in1 (т.е. съвпадащи битове) 12 0010 0B088544 0E2010FA 875E4400 00000400 BR.RET.SPTK rp 12 11000000 01008000 84A43980 00008400 E2K GAS nsamebit.s page 1 1 ! Да се напише подпрограма, която да връща в регистър r0 броя на съвпадащите 2 ! битове на една и съща позиция в думите, подадени в регистри r0, r1 и r2. 3 4 .global nsamebit 5 nsamebit: 6 { disp %ctpr1,L1 ! Подготви прехода към началото на цикъла 7 0000 12400004 81818009 06000040 00000000 xord %r0,%r1,%r1}!r1 ^= r0 (съвпадащите битове стават 0, другите 1) 8 { xor_ord %r0,%r2,%r1,%r1!r1 = r1 ^ r0 | r2 ^ r0 (" " " " " ") 9 0010 12402008 81828049 000000F0 00008108 return %ctpr3 } ! Подготви връщането към извикващата функция 10 { xornd %r1,0,%r1 !Съвпадащите битове стават лог.1, несъвпадащите – 0 11 0020 1200000C 81C0810B 80808009 00000000 xord %r0,%r0,%r0}! Инициализирай брояча на лог. единици 12 L1: { cmpldb %r1,0,%pred0! %pred0 = бит 63 (знаковия бит) 13 cmpedb %r1,0,%pred1! Има ли още лог. 1 за преброяване? 14 0030 1300001C C0C08121 41C08121 81C18119 shld %r1,1,%r1 } ! (подготви следващия бит като най-старши и преброй 15 { addd %r0,1,%r0 ? %pred0! поредния бит като съвпадащ, ако е лог. 1) 16 0040 12100104 610400C0 80C18011 00006004 ct %ctpr1 ? ~%pred1}!Да, повтаряй, докато има още лог.единици в r1 17 0050 01100000 200C00C0 ct %ctpr3 ! Не, r0 = брой единици в r1, т.е. съвпадащи битове S/390x LISTING bitr128.s page 1 1 # Да се напише подпрограма, която да записва по адрес в регистър 2 двойната 2 # дума, чийто адрес ѝ е подаден в регистър 3, с огледално обърнати битове. 3 4 .global bitr128 5 bitr128: 6 0000 EB343000 0004 LMG 3,4,0(3) # Зареди аргумента в регистри 7 0006 A709003F LGHI 0,63 # Инициализирай брояча на битове 8 000a EC143FBF 0155 RISBG 1,4,63,0b10000000+63,1#Съхрани най-старшия бит на младшата дума 9 0010 B9040053 LGR 5,3 # като най-младши, както и цялата старша дума 10 0014 EC343F3F 0055 L1: RISBG 3,4,63,63,0 # Копирай най-младшия бит на младшата дума 11 001a EB440001 000C SRLG 4,4,1 # Измести надясно младшата дума 12 0020 EB330001 001C RLLG 3,3,1 # Завърти с 1 бит наляво старшата дума 13 0026 EC430000 3F55 RISBG 4,3,0,0,63 # Запиши бившия най-старши бит на старшата дума 14 002c A707FFF4 BRCTG 0,L1 # Премини към следващата итерация на цикъла 15 0030 EB440001 000C SRLG 4,4,1 # Измести надясно младшата дума 16 0036 EC450000 3F55 RISBG 4,5,0,0,63 # Копирай най-младшия бит като най-старши 17 003c EC313F3F 0055 RISBG 3,1,63,63,0 # и най-старшия бит като най-младши 18 0042 EB342000 0024 STMG 3,4,0(2) # Съхрани резултата 19 0048 07FE0707 BR 14 AMD64 GAS bitr128.s page 1 1 # Да се напише подпрограма, която да връща в регистри RDX:RAX двойната дума в 2 # регистри RSI:RDI с огледално обърнати битове. 3 4 .intel_syntax noprefix 5 .global bitr128 6 bitr128: 7 0000 B9400000 00 MOV ECX,64 # Инициализирай брояча на битове 8 0005 48D1E6 SHL RSI,1 # Изведи най-старшия бит в CF 9 0008 48D1DF L1: RCR RDI,1 # Въведи най-старшия бит от CF, изведи най-младшия 10 000b 48D1D6 RCL RSI,1 # Въведи най-младшия бит от CF, изведи най-старшия 11 000e E2F8 LOOP L1 # Следваща итерация на цикъла 12 0010 4897 XCHG RAX,RDI 13 0012 4889F2 MOV RDX,RSI # Върни двойната дума в RDX:RAX 14 0015 C3 RET AARCH64 GAS bitr128.s page 1 1 // Да се напише подпрограма, която да обръща огледално битовете на двойната 2 // дума в регистри X1:X0 (командата RBIT я има във всички процесори ARMv8) 3 4 .global bitr128 5 bitr128: 6 0000 E20301AA MOV X2,X1 7 0004 0100C0DA RBIT X1,X0 8 0008 4000C0DA RBIT X0,X2 9 000c C0035FD6 RET ARC GAS bitr128.s page 1 1 # Да се напише подпрограма, която да обръща огледално битовете на двойната 2 # дума в регистри r1:r0. 3 4 .global bitr128 5 bitr128: 6 0000 0059 4180 ADDL.F r1,r1,r1# Изведи най-старшия бит в C 7 0004 40DB MOVL_S r3,64 # Задай брой итерации 8 0006 0442 L1: MOVL_S r2,r0 # Съхрани старата стойност, от която ще дойде новият C 9 0008 6158 4000 LSRL r0,r0,1 # Уви, в ARCv3 няма команда „RRCL“, затова я емулираме! 10 000c CF58 E50F BSETL.CS r0,r0,63# Въведи най-старшия бит от C 11 0010 615A 7E80 LSRL.F 0,r2,1 # и изведи там най-младшия – от старата стойност на r0 12 0014 0159 4180 ADCL.F r1,r1,r1# Въведи най-младшия бит от C, изведи там най-старшия 13 0018 8C23 FF0D DBNZ r3,L1 # Следваща итерация на цикъла 14 001c E07E J_S [blink] PPC LISTING bitr128.s page 1 1 # Да се напише подпрограма, която да обръща огледално битовете на двойната 2 # дума в регистри r3:r4. 3 4 .global bitr128 5 bitr128: 6 0000 38A0003F li r5,63 # Инициализирай брояча на битове 7 0004 7CA903A6 mtctr r5 8 0008 78850FE0 rldicl r5,r4,1,63 # Съхрани най-старшия бит на младшата дума като 9 000c 7C661B78 mr r6,r3 # най-младши, както и цялата старша дума 10 0010 788307EC L1: rldimi r3,r4,0,63 # Копирай най-младшия бит на младшата дума 11 0014 7884F842 rldicl r4,r4,63,1 # Измести надясно младшата дума 12 0018 78630800 rldicl r3,r3,1,0 # Завърти с 1 бит наляво старшата дума 13 001c 7864F80E rldimi r4,r3,63,0 # Запиши бившия най-старши бит на старшата дума 14 0020 4200FFF0 bdnz L1 # Следваща итерация на цикъла 15 0024 7884F842 rldicl r4,r4,63,1 # Измести надясно младшата дума 16 0028 78C4F80E rldimi r4,r6,63,0 # Копирай най-младшия бит като най-старши 17 002c 78A307EC rldimi r3,r5,0,63 # и най-старшия бит като най-младши 18 0030 4E800020 blr SPARC GAS bitr128.s page 1 1 ! Да се напише подпрограма, която да обръща огледално битовете на двойната 2 ! дума в регистри %o0:%o1. 3 4 .global bitr128 5 bitr128: 6 0000 17200000 972AF020 setx 0x8000000000000000,%o2,%o3! Подготви маска за най-старшия бит 7 0008 94102040 mov 64,%o2 ! Инициализирай брояча на битове 8 000c 980A000B and %o0,%o3,%o4 ! Отдели най-старшия бит в %o4 9 0010 912A3001 sllx %o0,1,%o0 ! Направи място за най-младшия бит в ст. дума 10 0014 9A0A6001 L1: and %o1,1,%o5 ! Отдели най-младшия бит в %o5 11 0018 93327001 srlx %o1,1,%o1 ! Направи място за най-старшия бит 12 001c 9212400C or %o1,%o4,%o1 ! и го въведи в младшата дума 13 0020 980A000B and %o0,%o3,%o4 ! Отдели най-старшия бит 14 0024 912A3001 sllx %o0,1,%o0 ! Направи място за най-младшия бит 15 0028 9012000D or %o0,%o5,%o0 ! и го въведи в старшата дума 16 002c 94A2A001 deccc %o2 ! Следваща итерация на цикъла? 17 0030 126FFFF9 bne %xcc,L1 ! Да, продължи 18 0034 01000000 nop ! Не, върни новата стойност 19 0038 81C3E008 retl 20 003c 01000000 nop MIPS LISTING bitr128.s page 1 1 # Да се напише подпрограма, която да връща в регистри $2:$3 двойната дума в 2 # регистри $4:$5 с огледално обърнати битове. 3 4 .ent bitr128 5 .global bitr128 6 bitr128: 7 0000 2403003F LI $3,63 # Инициализирай брояча на битове 8 0004 7CA707C2 DEXTU $7,$5,63,1 # Съхрани най-старшия бит на младшата дума като 9 0008 00801025 MOVE $2,$4 # най-младши, както и цялата старша дума 10 000c 7CA20007 L1: DINS $2,$5,0,1 # Копирай най-младшия бит на младшата дума 11 0010 0005287A DSRL $5,$5,1 # Измести надясно младшата дума 12 0014 002217FE DROTR32 $2,$2,31 # Завърти с 1 бит наляво старшата дума 13 0018 7C45FFC6 DINSU $5,$2,63,1 # Запиши бившия най-старши бит на старшата дума 14 001c 6463FFFF DADDIU $3,-1 # Ако има още битове, 15 0020 1460FFFA 00000000 BNE $3,$0,L1 # премини към следващата итерация на цикъла 16 0028 0005187A DSRL $3,$5,1 # Измести надясно младшата дума 17 002c 7C83FFC6 DINSU $3,$4,63,1 # Копирай най-младшия бит като най-старши 18 DINS $2,$7,0,1 # и най-старшия бит като най-младши 19 0030 03E00008 7CE20007 JR $31 20 0038 00000000 00000000 .end bitr128 RISC-V LISTING bitr128.s page 1 1 # Да се напише подпрограма, която да обръща огледално битовете на двойната 2 # дума в регистри a1:a0 3 4 .global bitr128 5 bitr128: 6 0000 13060004 LI a2,64 # Инициализирай брояча на битове 7 0004 93169603 SLLI a3,a2,63 - 6 # Подготви маска за най-старшия бит 8 0008 33F7D500 AND a4,a1,a3 # Отдели най-старшия бит в a4 9 000c 93951500 SLLI a1,a1,1 # Направи място за най-младшия бит в ст. дума 10 0010 93771500 L1: AND a5,a0,1 # Отдели най-младшия бит в a5 11 0014 13551500 SRLI a0,a0,1 # Направи място за най-старшия бит 12 0018 3365E500 OR a0,a0,a4 # и го въведи в младшата дума 13 001c 33F7D500 AND a4,a1,a3 # Отдели най-старшия бит 14 0020 93951500 SLLI a1,a1,1 # Направи място за най-младшия бит 15 0024 B3E5F500 OR a1,a1,a5 # и го въведи в старшата дума 16 0028 1306F6FF ADDI a2,a2,-1 # Следваща итерация на цикъла? 17 002c E31206FE BNEZ a2,L1 # Да, продължи 18 0030 67800000 RET # Не, върни новата стойност LOONGARCH64 GAS bitr128.s page 1 1 # Да се напише подпрограма, която да обръща огледално битовете на двойната 2 # дума в регистри r5:r4 3 4 .global bitr128 5 bitr128: 6 0000 A6001500 OR $r6,$r5,$r0 7 0004 85540000 BITREV.D $r5,$r4 8 0008 C4540000 BITREV.D $r4,$r6 9 000c 2000004C JIRL $r0,$r1,0 # Да се напише подпрограма, която да записва по адреса в регистър $16 bitr128.o: file format ecoff-littlealpha # двойната дума в регистри $18:$17 с огледално обърнати битове. Disassembly of section .text: .ent bitr128 .globl bitr128 0000000000000000 : bitr128: 0: 01 00 7f 20 lda t2,1(zero) lda $3,1($31) 4: 23 f7 67 48 sll t2,0x3f,t2 sll $3,63,$3 # Подготви маска за най-старшия бит 8: 40 00 5f 20 lda t1,64(zero) lda $2,64($31) # Инициализирай брояча на битове c: 04 00 43 46 and a2,t2,t3 and $18,$3,$4 # Отдели най-старшия бит в $4 10: 12 04 52 42 addq a2,a2,a2 sll $18,1,$18 # Направи място за най-младшия бит в ст. дума 14: 05 30 20 46 and a1,0x1,t4 L1: and $17,1,$5 # Отдели най-младшия бит в $5 18: 91 36 20 4a srl a1,0x1,a1 srl $17,1,$17 # Направи място за най-старшия бит 1c: 22 35 40 40 subq t1,0x1,t1 bis $17,$4,$17 # и го въведи в младшата дума 20: 11 04 24 46 or a1,t3,a1 and $18,$3,$4 # Отдели най-старшия бит 24: 04 00 43 46 and a2,t2,t3 sll $18,1,$18 # Направи място за най-младшия бит 28: 12 04 52 42 addq a2,a2,a2 bis $18,$5,$18 # и го въведи в старшата дума 2c: 12 04 45 46 or a2,t4,a2 subq $2,1,$2 # Следваща итерация на цикъла? 30: f8 ff 5f f4 bne t1,14 bne $2,L1 # Да, продължи 34: 00 00 30 b6 stq a1,0(a0) stq $17,0($16) # Не, запиши младшата 38: 08 00 50 b6 stq a2,8(a0) stq $18,8($16) # и старшата дума на резултата 3c: 01 80 fa 6b ret zero,(ra),0x1 ret # и върни управлението .end bitr128 GAS for MMIX bitr128.s page 1 1 % Да се напише подпрограма, която да връща в регистри $1:$0 двойната дума, 2 % чийто адрес ѝ е подаден в регистър $0, с огледално обърнати битове. 3 4 .global bitr128 5 bitr128: 6 0000 8D010000 LDO $1,$0,0 % Зареди двойната дума в регистри $1:$0 7 0004 8D000008 LDO $0,$0,8 8 0008 E0038000 SETH $3,0x8000 % Подготви маска за най-старшия бит 9 000c E3020040 SETL $2,64 % Инициализирай брояча на битове 10 0010 C8040103 AND $4,$1,$3 % Отдели най-старшия бит в $4 11 0014 3B010101 SLU $1,$1,1 % Направи място за най-младшия бит в ст. дума 12 0018 C9050001 L1: AND $5,$0,1 % Отдели най-младшия бит в $5 13 001c 3F000001 SRU $0,$0,1 % Направи място за най-старшия бит 14 0020 C0000004 OR $0,$0,$4 % и го въведи в младшата дума 15 0024 C8040103 AND $4,$1,$3 % Отдели най-старшия бит 16 0028 28010105 2ADDU $1,$1,$5 % Вмъкни най-младшия бит в старшата дума 17 002c 27020201 SUBU $2,$2,1 % Следваща итерация на цикъла? 18 0030 4B02FFFA BNZ $2,L1 % Да, продължи 19 0034 F8020000 POP 2,0 % Не, върни управлението HPPA64 LISTING bitr128.s page 1 1 ; Да се напише подпрограма, която да връща в регистри %R28:%R29 двойната дума в 2 ; %R26:%R25 с огледално обърнати битове. 3 4 .global bitr128 5 bitr128: 6 0000 3418007E LDI 63,%R24 ; Инициализирай брояча на битове 7 0004 D35A041A L1: SHRPD %R26,%R26,63,%R26; Подготви 1 нов най-младши бит на R26 8 0008 D3390419 SHRPD %R25,%R25,63,%R25; " " " " " " " " R25 9 000c 01781840 MTSAR %R24 ; Обнови позицията на бита за копиране 10 0010 D7BA061F DEPD %R26,%SAR,1,%R29 ; Копирай 1 бит на старшата дума в младшата 11 0014 AF1F5FD5 ADDIB,>= -1,%R24,L1 ; Следваща итерация (изпълнява се след „DEPD“) 12 0018 D799061F DEPD %R25,%SAR,1,%R28 ; Копирай 1 бит на младшата дума в старшата 13 001c E840D002 BVE,N (%R2) TILE-Gx GAS bitr128.s page 1 1 # Да се напише подпрограма, която да обръща огледално битовете на двойната 2 # дума в регистри r1:r0 3 4 .global bitr128 5 bitr128: 6 { MOVE r2,r1 7 0000 01704851 21F83B28 REVBITS r1,r0 } 8 { REVBITS r0,r2 9 0008 80704851 E0766A28 JR lr } IA-64 GAS bitr128.s page 1 1 // Да се напише подпрограма, която да връща в регистри r9:r8 2 // двойната дума в регистри in1:in0 с огледално обърнати битове. 3 4 .global bitr128 5 bitr128: 6 ALLOC loc0=ar.pfs,2,3,0,0 7 MOV loc1=ar.lc 8 MOV ar.lc=62 // Инициализирай брояча на битове с 63 минус 1 9 0000 0010150A 80053002 04650000 E00B2A00 EXTR.U loc2=in0,63,1 // Съхрани най-старшия бит на младшата дума като 10 MOV r9=in1 // най-младши, както и цялата старша дума 11 L1: DEP r9=in0,r9,0,1 // Копирай най-младшия бит на младшата дума 12 0010 01000000 010040F2 83002920 01080184 SHR.U in0=in0,1 // Измести надясно младшата дума 13 SHRP r9=r9,r9,63 // Завърти с 1 бит наляво старшата дума 14 0020 01000000 01009000 25E02700 2400F952 DEP in0=r9,in0,63,1 // Запиши бившия най-старши бит на старшата дума 15 BR.CLOOP.SPTK L1 // Премини към следващата итерация на цикъла 16 0030 02000000 01009048 247E2B00 94000140 SHR.U r8=in0,1 // Измести надясно младшата дума 17 DEP r8=in1,r8,63,1 // Копирай най-младшия бит като най-старши 18 0040 11000000 01000000 000200A0 E0FFFF48 DEP r9=loc2,r9,0,1 // и най-старшия бит като най-младши 19 0050 02000000 01008010 807C2900 11420040 MOV ar.lc=loc1 // Възстанови съхранения брояч 20 0060 00000000 01009020 25E02700 300AAA00 BR.RET.SPTK rp // и върни управлението 20 11000000 01000000 00020080 00008400 E2K GAS bitr128.s page 1 1 ! Да се напише подпрограма, която да обръща огледално битовете на двойната 2 ! дума в регистри r1:r0. 3 4 .global bitr128 5 bitr128: 6 { return %ctpr3 ! Подготви връщането към извикващата функция 7 ord 0,63,%r2 ! Инициализирай брояча на битове 8 0000 2340000C 82D4C005 83D0801F 000000F0 00000000 7F003F00 getfd %r0,1 << 6 | 63,%r3}!Съхрани бит 63 на младшата дума като бит 0 9 { insfd %r1,63 << 6 | 1,%r3,%r3 ! и бит 0 на старшата дума като бит 63 10 0018 22401004 83D4816D 03000040 0000830B 00000000 0000C10F disp %ctpr1,L1 } ! Подготви прехода към началото на цикъла 11 L1: { insfd %r1,1 << 6,%r0,%r1 ! Копирай най-младшия бит на младшата дума 12 0030 2200100C 81D4816D 80C1801B 0000800B 00000000 00004000 shrd %r0,1,%r0 } ! Измести надясно младшата дума 13 { insfd %r1,63 << 6,%r0,%r0! Копирай най-старшия бит на старшата дума 14 shld %r1,1,%r1 ! Измести наляво старшата дума 15 cmpbedb %r2,1,%pred0 ! Последна итерация на цикъла? 16 0048 3400103C 80D4816D 81C18119 82C18213 60C18221 0000800B 00000000 0000C00F subd %r2,1,%r2 } ! (намали стойността на брояча) 17 { ct %ctpr1 ? ~%pred0! Не, премини към следващата 18 0068 12100104 600400C0 80C1801B 00006004 shrd %r0,1,%r0 ? %pred0 }!Да, измести надясно младшата дума 19 { insfd %r3,63 << 6,%r0,%r0! Копирай бившия бит 0 на старшата дума като 20 insfd %r1,1 << 6,%r3,%r1 ! бит 63 на младшата и бившия бит 63 на 21 0078 2310300C 200C00C0 80D4836D 81D0816D 830B800B 4000C00F ct %ctpr3 } ! младшата като бит 0 на старшата S/390x LISTING ucnvrf.s page 1 1 # Познайте какво прави тази подпрограма: 2 3 .global ucnvrf 4 ucnvrf: 5 0000 C0400000 002B LARL 4,WGHTS 6 0006 A719000A LGHI 1,10 7 000a B9820055 XGR 5,5 8 000e E3302000 0090 L1: LLGC 3,0(2) 9 0014 A72B0001 AGHI 2,1 10 0018 A73BFFD0 AGHI 3,-'0' 11 001c E3004000 0090 LLGC 0,0(4) 12 0022 A74B0001 AGHI 4,1 13 0026 A71BFFFF AGHI 1,-1 14 002a A7840008 JE L2 15 002e B90C0003 MSGR 0,3 16 0032 B90A0050 ALGR 5,0 17 0036 A7F4FFEC J L1 18 003a B9820044 L2: XGR 4,4 19 003e B9870040 DLGR 4,0 20 0042 EC460005 0A7D CLGIJNE 4,10,L3 21 0048 B9820044 XGR 4,4 22 004c B90B0043 L3: SLGR 4,3 23 0050 B9040024 LGR 2,4 24 0054 07FE BR 14 25 0056 02040805 0A090703 WGHTS: .byte 2,4,8,5,10,9,7,3,6,11 25 060B AMD64 GAS ucnvrf.s page 1 1 # Познайте какво прави тази програма: 2 3 .intel_syntax noprefix 4 .global ucnvrf 5 ucnvrf: 6 0000 4889FE MOV RSI,RDI 7 0003 4831D2 XOR RDX,RDX 8 0006 488D4A0A LEA RCX,[RDX+10] 9 000a 488D3D1A 000000 LEA RDI,[RIP+WGHTS] 10 0011 F62439 L1: MUL BYTE PTR [RCX+RDI] 11 0014 6601C2 ADD DX,AX 12 0017 AC LODSB 13 0018 2C30 SUB AL,'0' 14 001a E2F5 LOOP L1 15 001c 92 XCHG EAX,EDX 16 001d F63439 DIV BYTE PTR [RCX+RDI] 17 0020 C1E808 SHR EAX,8 18 0023 3C0A CMP AL,10 19 0025 0F44C1 CMOVE EAX,ECX 20 0028 28D0 SUB AL,DL 21 002a C3 RET 22 002b 0B060307 090A0508 WGHTS: .byte 11,6,3,7,9,10,5,8,4,2,0 22 040200 AARCH64 GAS ucnvrf.s page 1 1 // Познайте какво прави тази подпрограма: 2 3 .global ucnvrf 4 ucnvrf: 5 0000 02000010 ADR X2,WGHTS 6 0004 E3031F2A MOV W3,WZR 7 0008 01144038 L1: LDRB W1,[X0],#1 8 000c 21C00051 SUB W1,W1,#'0' 9 0010 44144038 LDRB W4,[X2],#1 10 0014 9F2C0071 CMP W4,#11 11 0018 60000054 BEQ L2 12 001c 230C041B MADD W3,W1,W4,W3 13 0020 FAFFFF17 B L1 14 0024 6208C41A L2: UDIV W2,W3,W4 15 0028 408C041B MSUB W0,W2,W4,W3 16 002c 1F280071 CMP W0,#10 17 0030 E003801A CSEL W0,WZR,W0,EQ 18 0034 0000014B SUB W0,W0,W1 19 0038 C0035FD6 RET 20 .data 21 0000 02040805 WGHTS: .byte 2,4,8,5,10,9,7,3,6,11 21 0A090703 21 060B ARC GAS ucnvrf.s page 1 1 # Познайте какво прави тази подпрограма: 2 3 .global ucnvrf 4 ucnvrf: 5 0000 4A5A 0070 MOVL r58,0 6 0004 0A5A 800F 0000 0000 MOVL r2,WGHTS 7 000c C744 0000 0A00 MOVL_S r4,10 8 0012 0112 8304 L1: LDB.AB r3,[r2,1] 9 0016 0F2B 4300 MACU r3,r3,r1 10 001a 0110 8104 LDB.AB r1,[r0,1] 11 001e 4259 010C SUBL r1,r1,'0' 12 0022 8C24 7F0E DBNZ r4,L1 13 0026 695B C002 REMUL r0,r3,11 14 002a 6958 8002 REMUL r0,r0,10 15 002e 2378 SUBL_S r0,r0,r1 16 0030 E07E J_S [blink] 17 .data 18 0000 0002 0408 050A 0907 WGHTS: .byte 0,2,4,8,5,10,9,7,3,6 18 0306 PPC LISTING ucnvrf.s page 1 1 # Познайте какво прави тази подпрограма: 2 3 .global ucnvrf 4 ucnvrf: 5 0000 3CA00000 lis r5,(WGHTS-1)@highest 6 0004 60A50000 ori r5,r5,(WGHTS-1)@higher 7 0008 78A507C6 sldi r5,r5,32 8 000c 64A50000 oris r5,r5,(WGHTS-1)@h 9 0010 60A50000 ori r5,r5,(WGHTS-1)@l 10 0014 38C0000A li r6,10 11 0018 7CC903A6 mtctr r6 12 001c 38C00000 li r6,0 13 0020 3863FFFF addi r3,r3,-1 14 0024 8C830001 L1: lbzu r4,1(r3) 15 0028 3884FFD0 addi r4,r4,-'0 16 002c 8CE50001 lbzu r7,1(r5) 17 0030 42400010 bdz L2 18 0034 7CE439D2 mulld r7,r4,r7 19 0038 7CC63A14 add r6,r6,r7 20 003c 4BFFFFE8 b L1 21 0040 7CA63B92 L2: divdu r5,r6,r7 22 0044 7C6539D2 mulld r3,r5,r7 23 0048 7C633050 subf r3,r3,r6 24 004c 2823000A cmpldi r3,10 25 0050 40820008 bne L3 26 0054 38600000 li r3,0 27 0058 7C641850 L3: subf r3,r4,r3 28 005c 4E800020 blr 29 0060 02040805 WGHTS: .byte 2,4,8,5,10,9,7,3,6,11 29 0A090703 29 060B 30 006a 0000 .align 2 SPARC GAS ucnvrf.s page 1 1 ! Познайте какво прави тази подпрограма: 2 3 .global ucnvrf 4 ucnvrf: 5 0000 96100000 clr %o3 6 0004 1B000000 15000000 9A136000 9412A000 9B2B7020 9412800D setx WGHTS,%o5,%o2 7 001c D20A0000 L1: ldub [%o0],%o1 8 0020 90022001 add %o0,1,%o0 9 0024 92226030 sub %o1,'0',%o1 10 0028 1B000000 19000000 9A136000 98132000 9B2B7020 9813000D setx WGHTS+9,%o5,%o4 11 0040 80A2800C cmp %o2,%o4 12 0044 D80A8000 ldub [%o2],%o4 13 0048 1A680005 bcc %xcc,L2 14 004c 9402A001 add %o2,1,%o2 15 0050 984A400C mulx %o1,%o4,%o4 16 0054 10BFFFF2 ba L1 17 0058 9602C00C add %o3,%o4,%o3 18 005c 946AC00C L2: udivx %o3,%o4,%o2 19 0060 904A800C mulx %o2,%o4,%o0 20 0064 9022C008 sub %o3,%o0,%o0 21 0068 80A2200A cmp %o0,10 22 006c 12680003 bne %xcc,L3 23 0070 01000000 nop 24 0074 90100000 clr %o0 25 0078 90220009 L3: sub %o0,%o1,%o0 26 007c 81C3E008 retl 27 0080 01000000 nop 28 .data 29 0000 02040805 0A090703 060B WGHTS: .byte 2,4,8,5,10,9,7,3,6,11 MIPS LISTING ucnvrf.s page 1 1 # Познайте какво прави тази подпрограма: 2 3 .ent ucnvrf 4 .global ucnvrf 5 ucnvrf: 6 0000 3C060000 3C010000 64C60000 64210000 0006303C 00C1302D DLA $6,WGHTS 7 0018 3C070000 3C010000 64E70000 64210000 0007383C 00E1382D DLA $7,WGHTS+9 8 0030 00000013 MTLO $0 9 0034 90850000 L1: LBU $5,0($4) 10 0038 64840001 DADDIU $4,$4,1 11 003c 64A5FFD0 DADDIU $5,$5,-'0' 12 LBU $8,0($6) 13 0040 10C70004 90C80000 BEQ $6,$7,L2 14 0048 64C60001 DADDIU $6,$6,1 15 MADDU $8,$5 16 004c 1000FFF9 71050001 B L1 17 0054 00001012 L2: MFLO $2 18 0058 15000002 0048001F 0007000D 00001012 DDIVU $2,$8 19 0068 00001010 MFHI $2 20 006c 2404000A LI $4,10 21 0070 14800002 0044001F 0007000D 00001012 DDIVU $2,$4 22 0080 00001010 MFHI $2 23 DSUBU $2,$2,$5 24 0084 03E00008 0045102F JR $31 25 008c 02040805 0A090703 060B WGHTS: .byte 2,4,8,5,10,9,7,3,6,11 26 0096 00000000 00000000 0000 .end ucnvrf RISC-V LISTING ucnvrf.s page 1 1 # Познайте какво прави тази подпрограма: 2 3 .global ucnvrf 4 ucnvrf: 5 0000 17060000 13060600 LA a2,WGHTS 6 0008 93069600 ADDI a3,a2,9 7 000c 93070000 MV a5,x0 8 0010 83450500 L1: LBU a1,0(a0) 9 0014 13051500 ADDI a0,a0,1 10 0018 938505FD ADDI a1,a1,-'0' 11 001c 03470600 LBU a4,0(a2) 12 0020 630AD600 BEQ a2,a3,L2 13 0024 13061600 ADDI a2,a2,1 14 0028 3308B702 MUL a6,a4,a1 15 002c B3870701 ADD a5,a5,a6 16 0030 6FF01FFE J L1 17 0034 33F5E702 L2: REMU a0,a5,a4 18 0038 1307A000 LI a4,10 19 003c 3375E502 REMU a0,a0,a4 20 0040 3305B540 SUB a0,a0,a1 21 0044 67800000 RET 22 0048 02040805 0A090703 060B0000 WGHTS: .byte 2,4,8,5,10,9,7,3,6,11 LOONGARCH64 GAS ucnvrf.s page 1 1 # Познайте какво прави тази подпрограма: 2 3 .global ucnvrf 4 ucnvrf: 5 0000 0600001A C600C028 LA $r6,WGHTS 6 0008 C724C002 ADDI.D $r7,$r6,9 7 000c 09001500 OR $r9,$r0,$r0 8 0010 8500002A L1: LD.BU $r5,$r4,0 9 0014 8404C002 ADDI.D $r4,$r4,1 10 0018 A540FF02 ADDI.D $r5,$r5,-'0' 11 001c C800002A LD.BU $r8,$r6,0 12 0020 C7140058 BEQ $r6,$r7,L2 13 0024 C604C002 ADDI.D $r6,$r6,1 14 0028 0A951D00 MUL.D $r10,$r8,$r5 15 002c 29A91000 ADD.D $r9,$r9,$r10 16 0030 FFE3FF53 B L1 17 0034 24A12300 L2: MOD.DU $r4,$r9,$r8 18 0038 08288003 ORI $r8,$r0,10 19 003c 84A02300 MOD.DU $r4,$r4,$r8 20 0040 84941100 SUB.D $r4,$r4,$r5 21 0044 2000004C JIRL $r0,$r1,0 22 .data 23 0000 02040805 0A090703 WGHTS: .byte 2,4,8,5,10,9,7,3,6,11 23 060B ucnvrf.o: file format ecoff-littlealpha # Познайте какво прави тази подпрограма: Disassembly of section .text: .ent ucnvrf .globl ucnvrf 0000000000000000 : ucnvrf: 0: 10 80 3d a4 ldq t0,-32752(gp) lda $1,WGHTS 4: 0a 00 7f 20 lda t2,10(zero) lda $3,10($31) 8: 02 04 ff 47 clr t1 bis $31,$31,$2 c: 00 00 10 28 ldbu v0,0(a0) L1: ldbu $0,0($16) 10: 23 35 60 40 subq t2,0x1,t2 addq $16,1,$16 14: 20 15 06 40 subq v0,0x30,v0 subq $0,0x30,$0 18: 10 34 00 42 addq a0,0x1,a0 subq $3,1,$3 1c: 05 00 60 e4 beq t2,34 beq $3,L2 20: 00 00 81 28 ldbu t3,0(t0) ldbu $4,0($1) 24: 00 04 04 4c mulq v0,t3,v0 addq $1,1,$1 28: 01 34 20 40 addq t0,0x1,t0 mulq $0,$4,$0 2c: 02 04 02 40 addq v0,t1,t1 addq $0,$2,$2 30: f6 ff ff c3 br c br $31,L1 34: 18 80 3d a4 ldq t0,-32744(gp) L2: ldq $1,MAGIC 38: 00 00 21 a4 ldq t0,0(t0) 3c: 01 06 22 4c umulh t0,t1,t0 umulh $1,$2,$1 40: 1c 04 3f 40 addq t0,zero,at mulq $1,11,$1 44: 61 05 9c 43 s4subq at,at,t0 48: 61 05 3c 40 s4subq t0,at,t0 4c: 21 05 41 40 subq t1,t0,t0 subq $2,$1,$1 50: a2 55 21 40 cmpeq t0,0xa,t1 cmpeq $1,10,$2 54: c1 04 5f 44 cmovne t1,zero,t0 cmovne $2,$31,$1 58: 20 05 20 40 subq t0,v0,v0 subq $1,$0,$0 5c: 01 80 fa 6b ret zero,(ra),0x1 ret Contents of section .data: .data 0070 02040805 0a090703 06000000 00000000 WGHTS: .byte 2,4,8,5,10,9,7,3,6 0080 d245175d 74d14517 00000000 00000000 MAGIC: .quad 0x1745D1745D1745D2 .end ucnvrf GAS for MMIX ucnvrf.s page 1 1 % Познайте какво прави тази подпрограма: 2 3 .global ucnvrf 4 ucnvrf: 5 0000 23020000 LDA $2,WGHTS 6 0004 E303000A SETL $3,10 7 0008 C6050505 XOR $5,$5,$5 8 000c 83010000 L1: LDBU $1,$0,0 9 0010 23000001 ADDU $0,$0,1 10 0014 27010130 SUBU $1,$1,'0' 11 0018 27030301 SUBU $3,$3,1 12 001c 42030006 BZ $3,L2 13 0020 83040200 LDBU $4,$2,0 14 0024 23020201 ADDU $2,$2,1 15 0028 1A060401 MULU $6,$4,$1 16 002c 22050506 ADDU $5,$5,$6 17 0030 F1FFFFF7 JMP L1 18 0034 1F00050B L2: DIVU $0,$5,11 19 0038 FE000006 GET $0,rR 20 003c 1F00000A DIVU $0,$0,10 21 0040 FE000006 GET $0,rR 22 0044 26000001 SUBU $0,$0,$1 23 0048 F8010000 POP 1,0 24 004c 02040805 WGHTS: .byte 2,4,8,5,10,9,7,3,6 24 0A090703 24 06 HPPA64 LISTING ucnvrf.s page 1 1 ; Познайте какво прави тази подпрограма: 2 3 .global ucnvrf 4 ucnvrf: 5 0000 0802025F COPY %R2,%R31 6 0004 22E00000 LDIL L%WGHTS,%R23 7 0008 36F70000 LDO R%WGHTS(%R23),%R23 8 000c 34190000 LDI 0,%R25 9 0010 34140014 LDI 10,%R20 10 0014 0F421036 L1: LDB,MA 1(%R26),%R22 11 0018 B6D607A1 ADDI -'0,%R22,%R22 12 001c A69F2010 ADDIB,= -1,%R20,L2 13 0020 0EF60015 LDB %R22(%R23),%R21 14 0024 AB351FD5 ADDB,TR %R21,%R25,L1 15 0028 B6F70014 ADDI 10,%R23,%R23 16 002c 0B5A029A L2: XOR %R26,%R26,%R26 17 0030 34180016 LDI 11,%R24 18 0034 E800A000 B,L udiv128,%R2 19 0038 B6F7074D ADDI -90,%R23,%R23 20 003c 0EE010DD LDD 0(%R23),%R29 21 0040 93A07014 CMPICLR,> 10,%R29,%R0 22 0044 341D0000 LDI 0,%R29 23 0048 0BB6041C SUB %R22,%R29,%R28 24 004c EBE0D002 BVE,N (%R31) 25 .data 26 0000 00020406 WGHTS: .byte 0, 2, 4, 6, 8,10,12,14,16,18, 0, 4, 8,12,16,20,24,28,32,36 26 080A0C0E 26 10120004 26 080C1014 26 181C2024 27 0014 00081018 .byte 0, 8,16,24,32,40,48,56,64,72, 0, 5,10,15,20,25,30,35,40,45 27 20283038 27 40480005 27 0A0F1419 27 1E23282D 28 0028 000A141E .byte 0,10,20,30,40,50,60,70,80,90, 0, 9,18,27,36,45,54,63,72,81 28 28323C46 28 505A0009 28 121B242D 28 363F4851 29 003c 00070E15 .byte 0, 7,14,21,28,35,42,49,56,63, 0, 3, 6, 9,12,15,18,21,24,27 29 1C232A31 29 383F0003 29 06090C0F 29 1215181B 30 0050 00060C12 .byte 0, 6,12,18,24,30,36,42,48,54 30 181E242A 30 3036 UNDEFINED SYMBOLS udiv128 TILE-Gx GAS ucnvrf.s page 1 1 # Познайте какво прави тази подпрограма: 2 3 .global ucnvrf 4 ucnvrf: 5 0000 003048D1 E0070000 MOVELI r1,hw3_last(WGHTS) 6 0008 003048D1 20000038 SHL16INSLI r1,r1,hw2(WGHTS) 7 0010 003048D1 20000038 SHL16INSLI r1,r1,hw1(WGHTS) 8 0018 003048D1 20000038 SHL16INSLI r1,r1,hw0(WGHTS) 9 { MOVEI r3,10 10 0020 C3AF1040 E1FF3B28 MOVE r2,zero } 11 0028 003048D1 02084018 L1: LD1U_ADD r5,r0,1 12 { ADDI r5,r5,-'0' 13 0030 45011DC0 61F80F18 ADDI r3,r3,-1 } 14 0038 00304851 22084018 LD1U_ADD r4,r1,1 15 0040 00304851 61004014 BEQZ r3,L2 16 { MULA_LU_LU r2,r5,r4 17 0048 4241CC50 FEFFFF27 J L1 } 18 0050 003048D1 E077D105 L2: MOVELI r1,0xFFFFBA2E 19 0058 003048D1 20185D3C SHL16INSLI r1,r1,hw0(0x8BA3) 20 0060 4120F850 00306A28 MUL_LU_LU r1,r1,r2 21 0068 003048D1 20180B30 SHRUI r1,r1,35 22 0070 4140F850 00306A28 MUL_LU_LU r1,r1,r4 23 0078 003048D1 40086828 SUB r1,r2,r1 24 0080 00304851 21502018 CMPEQI r2,r1,10 25 0088 81F01B50 00306A28 CMOVNEZ r1,r2,zero 26 { SUB r0,r1,r5 27 0090 40504451 E0766A28 JR lr } 28 .data 29 0000 02040805 0A090703 WGHTS: .byte 2,4,8,5,10,9,7,3,6,11 29 060B IA-64 GAS ucnvrf.s page 1 1 // Познайте какво прави тази подпрограма: 2 3 .global ucnvrf 4 ucnvrf: 5 ALLOC r11=ar.pfs,1,0,0,0 6 MOVL r9=WGHTS 7 MOV r3=10 8 0000 04580402 80050000 00000020 01000060 MOV r2=r0 9 L1: LD1 r8=[in0],1 10 0010 00182800 00242000 00004200 00000400 SUB r3=r3,r0,1 11 ADD r8=-'0',r8 12 0020 0B400440 00143018 00084000 0145FC8C CMP.NE p6,p7=r3,r0 13 LD1 r10=[r9],1 14 (p6) SETF.SIG f6=r8 15 0030 09380C00 0638A008 24002800 00000400 (p6) SETF.SIG f7=r10 16 (p6) XMPY.LU f6=f6,f7 // „ski“ не поддържа MPY4 17 0040 CF302000 E1987150 00C23100 00000400 (p6) GETF.SIG r8=f6 18 (p6) ADD r2=r2,r8 19 0050 0D000000 01806100 180E7400 00000400 (p6) BR L1 20 0060 CA401800 E1902110 20004000 00000400 MOVL r9=0x1745D1745D1745D2 21 SETF.SIG f6=r2 22 0070 10000000 01000000 00020003 B0FFFF48 SETF.SIG f7=r9 23 0080 04000000 01005D74 D1451720 21E52E62 SETF.SIG f8=r10 24 0090 0A300800 E1187048 00C23100 00000400 XMPY.HU f6=f6,f7 25 XMPY.LU f6=f6,f8 26 00a0 0A402800 E1180000 00020000 00000400 GETF.SIG r9=f6 27 00b0 0D000000 01006000 180E7600 00000400 SUB r9=r2,r9 28 00c0 0D000000 01006000 18107400 00000400 CMP.EQ p6,p7=10,r9 29 00d0 0B481800 E1109010 240A4000 00000400 (p6) MOV r9=r0 30 SUB r8=r9,r8 31 00e0 0B302812 07B99100 00004200 00000400 BR.RET.SPTK rp 32 00f0 11402410 05200000 00020080 00008400 .data 33 0000 02040805 0A090703 060B WGHTS: .byte 2,4,8,5,10,9,7,3,6,11 E2K GAS ucnvrf.s page 1 1 ! Познайте какво прави тази подпрограма: 2 3 .global ucnvrf 4 ucnvrf: 5 { setwd wsz=6,nfx=1 6 disp %ctpr1,L1 7 0000 33C00004 82DDC005 06000040 00000000 00000000 00000000 00000000 D0000000 ord 0,[WGHTS],%r2 } 8 { return %ctpr3 9 ord 0,10,%r3 10 0020 1340000C 83CAC005 85858509 000000F0 xord %r5,%r5,%r5 } 11 L1: { ldb [%r0],%r1 12 0030 1200000C 81C08064 80C18011 00000000 addd %r0,1,%r0 } 13 { subd %r1,'0',%r1 14 0040 1200000C 81D48113 83C18313 00003000 subd %r3,1,%r3 } 15 0050 01010004 40C08321 cmpedb %r3,0,%pred0 16 { ldb [%r2],%r4 ? ~%pred0 17 0058 1200010C 84C08264 82C18211 0000E00D addd %r2,1,%r2 ? ~%pred0 } 18 0068 11001104 86818421 0000C001 0000E004 muld %r4,%r1,%r6 ? ~%pred0 19 { addd %r5,%r6,%r5 ? ~%pred0 20 0078 12100104 600400C0 85868511 0000E004 ct %ctpr1 ? ~%pred0 } 21 0088 01000080 85CB8545 umodx %r5,11,%r5 22 0090 01000080 85CA8545 umodx %r5,10,%r5 23 { subd %r5,%r1,%r0 24 0098 12100004 200C00C0 80818513 00000000 ct %ctpr3 } 25 .data 26 0000 02040805 0A090703 06 WGHTS: .byte 2,4,8,5,10,9,7,3,6 S/390x LISTING sequence.s page 1 1 # Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 # в регистър 2 първите 7 числа от редицата на Силвестър, първото от които е 3 # 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .global sequence 6 sequence: 7 0000 A7590007 LGHI 5,7 # Изваждащ брояч 8 0004 A7390001 LGHI 3,1 # Предидущо число 9 0008 B9040043 LGR 4,3 # Текущо число 10 000c B90C0034 L1: MSGR 3,4 # S[i] = S[i-1] * (S[i-1] - 1) 11 0010 41403001 LA 4,1(3) # S[i] = S[i-1] * (S[i-1] - 1) + 1 12 0014 E3402000 0024 STG 4,0(2) # Запиши S[i] в масива 13 001a A72B0008 AGHI 2,8 # Обнови адреса 14 001e A757FFF7 BRCTG 5,L1 # Премини към следващото число 15 0022 07FE BR 14 # Върни се към извикващата програма AMD64 GAS sequence.s page 1 1 # Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 # в регистър RDI първите 7 числа от редицата на Силвестър, първото от които е 3 # 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .intel_syntax noprefix 6 .global sequence 7 sequence: 8 0000 48C7C001 000000 MOV RAX,1 # Текущо число (MUL променя RDX -> неизползваем е) 9 0007 4889C1 L1: MOV RCX,RAX # Съхрани S[i-1] - 1 за следващата итерация 10 000a 48FFC0 INC RAX # S[i] = S[i-1] * (S[i-1] - 1) + 1 11 000d 48AB STOSQ # Запиши S[i] в масива 12 000f 48F7E1 MUL RCX # S[i] = S[i-1] * (S[i-1] - 1) 13 0012 73F3 JNC L1 # Ако старшата дума на произведението в RDX != 0, край 14 0014 C3 RET # Върни се към извикващата програма AARCH64 GAS sequence.s page 1 1 // Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 // в регистър X0 първите 7 числа от редицата на Силвестър, първото от които е 3 // 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .global sequence 6 sequence: 7 0000 210080D2 MOV X1,#1 // Текущо число 8 0004 22040091 L1: ADD X2,X1,#1 // S[i] = S[i-1] * (S[i-1] - 1) + 1 9 0008 028400F8 STR X2,[X0],#8 // запиши S[i] в масива 10 000c 237CC29B UMULH X3,X1,X2 // Побира ли се произведението в 64 бита? 11 0010 217C029B MUL X1,X1,X2 // все пак изчисли S[i] = S[i-1] * (S[i-1] - 1) 12 0014 83FFFFB4 CBZ X3,L1 // Да, премини към следващото число 13 0018 C0035FD6 RET // Не, върни се към извикващата програма ARC GAS sequence.s page 1 1 # Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 # в регистър r0 първите 7 числа от редицата на Силвестър, първото от които е 3 # 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .global sequence 6 sequence: 7 0000 07DB MOVL_S r3,7 # Изваждащ брояч 8 0002 01D9 MOVL_S r1,1 # Текущо число 9 0004 4059 4200 L1: ADDL r2,r1,1 # S[i] = S[i-1] * (S[i-1] - 1) + 1 10 0008 0818 9700 STL.AB r2,[r0,8] # запиши S[i] в масива и обнови адреса 11 000c 305A 4100 MPYL r1,r2,r1 # S[i] = S[i-1] * (S[i-1] - 1) 12 0010 8C23 BF0E DBNZ r3,L1 # Ако произведението се побира в 32 бита, 13 0014 E07E J_S [blink] # продължи, иначе върни управлението PPC LISTING sequence.s page 1 1 # Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 # в регистър r3 първите 7 числа от редицата на Силвестър, първото от които е 3 # 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .global sequence 6 sequence: 7 0000 3863FFF8 addi r3,r3,-8# Компенсирай автоматичното предварително увеличение 8 0004 38800007 li r4,7 # Изваждащ брояч 9 0008 7C8903A6 mtctr r4 10 000c 38800001 li r4,1 # Предидущо число 11 0010 38A00001 li r5,1 # Текущо число 12 0014 7C8429D2 L1: mulld r4,r4,r5# S[i] = S[i-1] * (S[i-1] - 1) 13 0018 38A40001 addi r5,r4,1 # S[i] = S[i-1] * (S[i-1] - 1) + 1 14 001c F8A30009 stdu r5,8(r3)# Запиши S[i] в масива 15 0020 4200FFF4 bdnz L1 # Премини към следващото число 16 0024 4E800020 blr # Върни се към извикващата програма SPARC GAS sequence.s page 1 1 ! Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 ! в регистър %o0 първите 7 числа от редицата на Силвестър, първото от които е 3 ! 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .global sequence 6 sequence: 7 0000 92102001 mov 1,%o1 ! Предидущо число 8 0004 94102001 mov 1,%o2 ! Текущо число 9 0008 96102007 mov 7,%o3 ! Изваждащ брояч 10 000c 924A400A L1: mulx %o1,%o2,%o1! S[i] = S[i-1] * (S[i-1] - 1) 11 0010 94026001 add %o1,1,%o2 ! S[i] = S[i-1] * (S[i-1] - 1) + 1 12 0014 D4720000 stx %o2,[%o0] ! Запиши S[i] в масива 13 0018 90022008 add %o0,8,%o0 ! Обнови адреса 14 001c 96A2E001 subcc %o3,1,%o3 ! Намали съдържанието на брояча; i == 7? 15 0020 126FFFFB bne %xcc,L1 ! Не, премини към следващото число 16 0024 01000000 nop ! Да, върни се към извикващата програма 17 0028 81C3E008 retl 18 002c 01000000 nop MIPS LISTING sequence.s page 1 1 # Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 # в регистър $4 първите 7 числа от редицата на Силвестър, първото от които е 3 # 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .ent sequence 6 .global sequence 7 sequence: 8 0000 24070007 LI $7,7 # Изваждащ брояч 9 0004 24050001 LI $5,1 # Предидущо число 10 0008 24060001 LI $6,1 # Текущо число 11 000c 00A6001D L1: DMULTU $5,$6 12 0010 00002812 MFLO $5 # S[i] = S[i-1] * (S[i-1] - 1) 13 0014 64A60001 DADDIU $6,$5,1 # S[i] = S[i-1] * (S[i-1] - 1) + 1 14 0018 FC860000 SD $6,0($4)# Запиши S[i] в масива 15 001c 64840008 DADDIU $4,$4,8 # Укажи към следващия елемент на масива 16 0020 64E7FFFF DADDIU $7,$7,-1# Има ли още числа? 17 0024 14E0FFF9 00000000 BNE $7,$0,L1# Да, премини към следващото 18 002c 03E00008 00000000 JR $31 # Не, върни се към извикващата програма 19 0034 00000000 00000000 00000000 .end sequence RISC-V LISTING sequence.s page 1 1 # Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 # в регистър a0 първите 7 числа от редицата на Силвестър, първото от които е 3 # 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .global sequence 6 sequence: 7 0000 93067000 LI a3,7 # Изваждащ брояч 8 0004 93051000 LI a1,1 # Предидущо число 9 0008 13061000 LI a2,1 # Текущо число 10 000c B385C502 L1: MUL a1,a1,a2 # S[i] = S[i-1] * (S[i-1] - 1) 11 0010 13861500 ADDI a2,a1,1 # S[i] = S[i-1] * (S[i-1] - 1) + 1 12 0014 2330C500 SD a2,0(a0) # Запиши S[i] в масива 13 0018 13058500 ADDI a0,a0,8 # Укажи към следващия елемент на масива 14 001c 9386F6FF ADDI a3,a3,-1 # Има ли още числа? 15 0020 E39606FE BNEZ a3,L1 # Да, премини към следващото 16 0024 67800000 RET # Не, върни се към извикващата програма LOONGARCH64 GAS sequence.s page 1 1 # Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 # в регистър r4 първите 7 числа от редицата на Силвестър, първото от които е 3 # 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .global sequence 6 sequence: 7 0000 071C8003 ORI $r7,$r0,7 # Изваждащ брояч 8 0004 05048003 ORI $r5,$r0,1 # Предидущо число 9 0008 06048003 ORI $r6,$r0,1 # Текущо число 10 000c A5981D00 L1: MUL.D $r5,$r5,$r6 # S[i] = S[i-1] * (S[i-1] - 1) 11 0010 A604C002 ADDI.D $r6,$r5,1 # S[i] = S[i-1] * (S[i-1] - 1) + 1 12 0014 8600C029 ST.D $r6,$r4,0 # Запиши S[i] в масива 13 0018 8420C002 ADDI.D $r4,$r4,8 # Укажи към следващия елемент на масива 14 001c E7FCFF02 ADDI.D $r7,$r7,-1 # Има ли още числа? 15 0020 FFECFF47 BNEZ $r7,L1 # Да, премини към следващото 16 0024 2000004C JIRL $r0,$r1,0 # Не, върни се към извикващата програма # Да се напише подпрограма, която да записва в масив от думи с начален адрес # в регистър $16 първите 7 числа от редицата на Силвестър, първото от които е sequence.o: file format ecoff-littlealpha # 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. Disassembly of section .text: .ent sequence .globl sequence 0000000000000000 : sequence: 0: 07 00 5f 20 lda t1,7(zero) lda $2,7($31) # Изваждащ брояч 4: 01 00 1f 20 lda v0,1(zero) lda $0,1($31) # Предидущо число 8: 01 00 3f 20 lda t0,1(zero) lda $1,1($31) # Текущо число c: 00 04 01 4c mulq v0,t0,v0 L1: mulq $0,$1,$0 # S[i] = S[i-1] * (S[i-1] - 1) 10: 22 35 40 40 subq t1,0x1,t1 addq $0,1,$1 # S[i] = S[i-1] * (S[i-1] - 1) + 1 14: 01 34 00 40 addq v0,0x1,t0 stq $1,0($16) # Запиши S[i] в масива 18: 00 00 30 b4 stq t0,0(a0) addq $16,8,$16 # Укажи към следващия елемент на масива 1c: 10 14 01 42 addq a0,0x8,a0 subq $2,1,$2 # Има ли още числа? 20: fa ff 5f f4 bne t1,c bne $2,L1 # Да, премини към следващото 24: 01 80 fa 6b ret zero,(ra),0x1 ret # Не, върни се към извикващата програма 28: 1f 04 ff 47 nop .end sequence 2c: 00 00 fe 2f unop GAS for MMIX sequence.s page 1 1 % Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 % в регистър $0 първите 7 числа от редицата на Силвестър, първото от които е 3 % 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .global sequence 6 sequence: 7 0000 E3030007 SETL $3,7 % Изваждащ брояч 8 0004 E3010001 SETL $1,1 % Предидущо число 9 0008 E3020001 SETL $2,1 % Текущо число 10 000c 1A010102 L1: MULU $1,$1,$2 % S[i] = S[i-1] * (S[i-1] - 1) 11 0010 23020101 ADDU $2,$1,1 # S[i] = S[i-1] * (S[i-1] - 1) + 1 12 0014 AF020000 STOU $2,$0,0 % Запиши S[i] в масива 13 0018 23000008 ADDU $0,$0,8 % Укажи към следващия елемент на масива 14 001c 27030301 SUBU $3,$3,1 % Има ли още числа? 15 0020 4B03FFFB BNZ $3,L1 % Да, премини към следващото 16 0024 F8000000 POP 0,0 % Не, върни се към извикващата програма HPPA64 LISTING sequence.s page 1 1 ; Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 ; в регистър %R26 първите 7 числа от редицата на Силвестър, първото от които 3 ; е 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .global sequence 6 sequence: 7 0000 34190002 LDI 1,%R25 ; Предидущо число 8 0004 08190258 COPY %R25,%R24 ; Текущо число 9 0008 3417000E LDI 7,%R23 ; Изваждащ брояч 10 000c 0FD912F0 L1: STD,MA %R25,8(%SP) ; Множителите се предават чрез стека 11 0010 E8200000 B,L UM64X64,%R1 ; R29 = младша дума на произведението 12 0014 0FD812F0 STD,MA %R24,8(%SP) ; Изпълнява се преди „B,L“! 13 0018 081D0259 COPY %R29,%R25 ; S[i] = S[i-1] * (S[i-1] - 1) 14 001c B7380002 ADDI 1,%R25,%R24 ; S[i] = S[i-1] * (S[i-1] - 1) + 1 15 0020 AEFFBFCD ADDIB,*<> -1,%R23,L1 ; Премини към следващото число 16 0024 0F5812F0 STD,MA %R24,8(%R26) ; Запиши S[i] в масива (изп. се преди „ADDIB“!) 17 0028 E840D002 BVE,N (%R2) ; Върни се към извикващата програма UNDEFINED SYMBOLS UM64X64 TILE-Gx GAS sequence.s page 1 1 # Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 # в регистър r0 първите 7 числа от редицата на Силвестър, първото от които е 3 # 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .global sequence 6 sequence: 7 0000 003048D1 E13F0818 MOVEI r3,7 # Изваждащ брояч 8 { MOVEI r1,1 # Предидущо число 9 0008 C11F1040 E10F0818 MOVEI r2,1 } # Текущо число 10 0010 4120F850 00306A28 L1: MUL_LU_LU r1,r1,r2 # S[i] = S[i-1] * (S[i-1] - 1) 11 0018 00304851 21080818 ADDI r2,r1,1 # S[i] = S[i-1] * (S[i-1] - 1) + 1 12 { ST_ADD r0,r2,8 # Запиши S[i] в масива и обнови адреса 13 0020 C3F01F40 04100019 ADDI r3,r3,-1 } # Има ли още числа? 14 0028 003048D1 7EF8BF17 BNEZT r3,L1 # Да, премини към следващото 15 0030 00304851 E0766A28 JR lr # Не, върни се към извикващата програма IA-64 GAS sequence.s page 1 1 // Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 // в регистър in0 първите 7 числа от редицата на Силвестър, първото от които е 3 // 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .global sequence 6 sequence: 7 ALLOC loc3=ar.pfs,1,4,0,0 8 MOV loc2=ar.lc 9 MOV ar.lc=6 // Инициализирай брояча на цикъла с 7 минус 1 10 0000 0020150A 80053002 04650000 60082A00 MOV loc0=1 // Предидущо число 11 MOV loc1=loc0 // Текущо число 12 L1: SETF.SIG f6=loc0 // Копирай множителите 13 0010 0A080500 00242002 84004200 00000400 SETF.SIG f7=loc1 14 XMPY.LU f6=f6,f7 // „ski“ не поддържа MPY4 15 0020 0B308400 E1187010 01C23100 00000400 GETF.SIG loc0=f6 // S[i] = S[i-1] * (S[i-1] - 1) 16 ADD loc1=loc0,r0,1 // S[i] = S[i-1] * (S[i-1] - 1) + 1 17 0030 0D000000 01006000 180E7400 00000400 ST8 [in0]=loc1,8 // Запиши S[i] в масива и обнови адреса 18 0040 0B081900 E110200A 01024000 00000400 BR.CLOOP.SPTK L1 // Премини към следващата итерация на цикъла 19 MOV ar.lc=loc2 // Възстанови съхранения брояч 20 0050 11408840 98150000 000200A0 D0FFFF48 BR.RET.SPTK rp // и върни управлението 20 11000000 01000018 05550080 00008400 E2K GAS sequence.s page 1 1 ! Да се напише подпрограма, която да записва в масив от думи с начален адрес 2 ! в регистър r0 първите 7 числа от редицата на Силвестър, първото от които е 3 ! 2, а всяко следващо е равно на произведението на всички предидущи плюс 1. 4 5 .global sequence 6 sequence: 7 { disp %ctpr1,L1 ! Подготви прехода в началото на цикъла 8 0000 12400004 83C7C005 04000040 00000000 ord 0,7,%r3 } ! Изваждащ брояч 9 { return %ctpr3 ! Подготви връщането към извикващата функция 10 ord 0,1,%r1 ! Предидущо число 11 0010 1340000C 81C1C005 82C1C005 000000F0 ord 0,1,%r2 } ! Текущо число 12 0020 11001004 81828121 0000C001 00000000 L1: muld %r1,%r2,%r1 ! S[i] = S[i-1] * (S[i-1] - 1) 13 0030 01000004 82C18111 addd %r1,1,%r2 ! S[i] = S[i-1] * (S[i-1] - 1) + 1 14 { std %r2,[%r0] ! Запиши S[i] в масива 15 addd %r0,8,%r0 ! Укажи към следващия елемент на масива 16 cmpbedb %r3,1,%pred0 ! Има ли още числа? 17 0038 2400003C 80C88011 60C18321 82C08027 83C18313 00000000 subd %r3,1,%r3 } ! (намали стойността на брояча) 18 0050 01100000 600400C0 ct %ctpr1 ? ~%pred0! Да, премини към следващото 19 0058 01100000 200C00C0 ct %ctpr3 ! Не, върни се към извикващата програма S/390x LISTING srch128.s page 1 1 # Да се напише подпрограма, която да връща в регистър 2 индекса на двойната 2 # дума, чийто адрес ѝ е подаден в същия регистър, в масива от двойни думи (BE) 3 # с начален адрес в реигистър 4 и брой елементи в регистър 3, или -1, ако не е 4 # намерена. 5 6 .global srch128 7 srch128: 8 0000 E360F010 0024 STG 6,16(15)# Съхрани използвания регистър (LNUX-1007-02) 9 0006 EB562000 0004 LMG 5,6,0(2)# Зареди аргумента в регистри 10 000c A729FFFF LGHI 2,-1 # Инициализирай индекса 11 0010 A72B0001 L1: AGHI 2,1 # Актуализирай го 12 0014 EB014000 0004 LMG 0,1,0(4)# Зареди следващата двойна дума 13 001a A74B0010 AGHI 4,16 # Обнови адреса 14 001e EC610006 6065 CLGRJNE 6,1,L2 # Съвпадат ли младшите думи? 15 0024 EC500007 8065 CLGRJE 5,0,L3 # Да, съвпадат ли и старшите? 16 002a A737FFF3 L2: BRCTG 3,L1 # Не, продължи със следващия елемент 17 002e A729FFFF LGHI 2,-1 # Двойната дума в регистри 5:6 не е намерена, върни -1 18 0032 E360F010 0004 L3: LG 6,16(15)# Възстанови съхранения регистър 19 0038 07FE0707 BR 14 # Върни индекса на откритата съвпадаща двойна дума AMD64 GAS srch128.s page 1 1 # Да се напише подпрограма, която да връща в регистър EAX индекса на подадената 2 # в регистри RSI:RDI двойна дума в масива от двойни думи с начален адрес в RCX 3 # и брой елементи в регистър RDX или -1, ако не е намерена. 4 5 .intel_syntax noprefix 6 .global srch128 7 srch128: 8 0000 4887D1 XCHG RCX,RDX # RCX = брой елементи, RDX = начален адрес на масива 9 0003 4831C0 XOR RAX,RAX # Инициализирай удвоения индекс 10 0006 483B3CC2 L1: CMP RDI,[RDX+8*RAX] # Съвпадат ли младшите думи? 11 000a 7507 JNE L2 # Не, прескочи сравнението на старшите 12 000c 483B74C2 08 CMP RSI,[RDX+8*RAX+8]# Да, съвпадат ли старшите думи? 13 0011 740A JE L3 # Да, излез от цикъла 14 0013 4883C002 L2: ADD RAX,2 # Не, актуализирай удвоения индекс 15 0017 E2ED LOOP L1 16 0019 488D41FE LEA RAX,[RCX-2]# Двойната дума в RSI:RDI не е намерена, върни -1 17 001d 48D1E8 L3: SHR RAX,1 # EAX (RAX) = индекс на откритата двойна дума или -1 18 0020 C3 RET AARCH64 GAS srch128.s page 1 1 // Да се напише подпрограма, която да връща в регистър X0 индекса на подадената 2 // в регистри X1:X0 двойна дума в масива от двойни думи (LE) с начален адрес в 3 // регистър X3 и брой елементи в регистър X2, или -1, ако не е намерена. 4 5 .global srch128 6 srch128: 7 0000 04008092 MOV X4,#-1 // Инициализирай индекса 8 0004 84040091 L1: ADD X4,X4,#1 // Актуализирай го 9 0008 6518C1A8 LDP X5,X6,[X3],#16// Зареди следващата двойна дума и обнови адреса 10 000c 1F0005EB CMP X0,X5 // Съвпадат ли младшите думи? 11 0010 200046FA CCMP X1,X6,#0,EQ // Да, съвпадат ли и старшите? 12 0014 80000054 BEQ L2 // Да, излез от цикъла 13 0018 420400F1 SUBS X2,X2,#1 // Не, продължи със следващия елемент 14 001c 41FFFF54 BNE L1 15 0020 04008092 MOV X4,#-1 // Двойната дума в X1:X0 не е намерена, върни -1 16 0024 E00304AA L2: MOV X0,X4 // Върни индекса на откритата съвпадаща двойна дума 17 0028 C0035FD6 RET // Върни управлението ARC GAS srch128.s page 1 1 # Да се напише подпрограма, която да връща в регистър r0 индекса на подадената 2 # в регистри r1:r0 двойна дума в масива от двойни думи (LE) с начален адрес в 3 # регистър r3 и брой елементи в регистър r2, или -1, ако не е намерена. 4 5 .global srch128 6 srch128: 7 0000 6F5E 0A00 NOTL r6,0 # Инициализирай индекса с -1 8 0004 405E 4600 L1: ADDL r6,r6,1 # Актуализирай го 9 0008 1013 C40E LDDL.AB r4,[r3,16]# Зареди следващата двойна дума 10 000c 0908 0901 BRNEL r0,r4,L2 # Съвпадат ли младшите думи? 11 0010 0D09 4801 BREQL r1,r5,L3 # Да, ако старшите думи съвпадат, излез от цикъла 12 0014 8C22 3F0E L2: DBNZ r2,L1 # Не, продължи със следващия елемент 13 0018 6F5E 0A00 NOTL r6,0 # Двойната дума в r1:r0 не е намерена, върни -1 14 001c C440 L3: MOVL_S r0,r6 # Върни индекса на откритата съвпадаща двойна дума 15 001e E07E J_S [blink] # Върни управлението PPC LISTING srch128.s page 1 1 # Да се напише подпрограма, която да връща в регистър r3 индекса на подадената 2 # в регистри r3:r4 двойна дума в масива от двойни думи (BE) с начален адрес в 3 # регистър r6 и брой елементи в регистър r5, или -1, ако не е намерена. 4 5 .global srch128 6 srch128: 7 0000 38C6FFF8 addi r6,r6,-8# Компенсирай автоматичното предварително увеличение 8 0004 7CA903A6 mtctr r5 # Инициализирай брояча на елементи 9 0008 38E0FFFF li r7,-1 # Инициализирай индекса 10 000c 38E70001 L1: addi r7,r7,1 # Актуализирай го 11 0010 E9060009 ldu r8,8(r6)# Зареди следващата двойна дума - първо старшата, 12 0014 E9260009 ldu r9,8(r6)# а после и младшата 13 0018 7C234040 cmpld r3,r8 # Съвпадат ли старшите думи? 14 001c 40820008 bne L2 # Не, продължи със следващия елемент 15 0020 7C244840 cmpld r4,r9 # Да, съвпадат ли и младшите? 16 0024 4002FFE8 L2: bdnzf eq,L1 # Не, продължи със следващия елемент 17 0028 41820008 beq L3 # Да, прескочи връщането на отрицателен индекс 18 002c 38E0FFFF li r7,-1 # Двойната дума в r3:r4 не е намерена, върни -1 19 0030 7CE33B78 L3: mr r3,r7 # Върни индекса на откритата съвпадаща двойна дума 20 0034 4E800020 blr # Върни управлението SPARC GAS srch128.s page 1 1 ! Да се напише подпрограма, която да връща в регистър %o0 индекса на подадената 2 ! в регистри %o0:%o1 двойна дума в масива от двойни думи (BE) с начален адрес в 3 ! регистър %o3 и брой елементи в регистър %o2, или -1, ако не е намерена. 4 5 .global srch128 6 srch128: 7 0000 82103FFF mov -1,%g1 ! Инициализирай индекса 8 0004 82006001 L1: add %g1,1,%g1 ! Актуализирай го 9 0008 D85AC000 ldx [%o3],%o4 ! Зареди следващата двойна дума – първо старшата, 10 000c DA5AE008 ldx [%o3+8],%o5 ! а след това и младшата 11 0010 9602E010 add %o3,16,%o3 ! Обнови адреса 12 0014 80A2400D cmp %o1,%o5 ! Съвпадат ли младшите думи? 13 0018 12680004 bne %xcc,L2 ! Не, продължи 14 001c 80A2000C cmp %o0,%o4 ! Да, съвпадат ли и старшите? 15 0020 02680006 beq %xcc,L3 ! Да, излез от цикъла 16 0024 01000000 nop 17 0028 94A2A001 L2: subcc %o2,1,%o2 ! Не, продължи със следващия елемент 18 002c 126FFFF6 bne %xcc,L1 19 0030 01000000 nop 20 0034 82103FFF mov -1,%g1 ! Двойната дума в %o0:%o1 не е намерена, върни -1 21 0038 81C3E008 L3: retl ! Изпълнява се след „mov“! 22 003c 90100001 mov %g1,%o0 ! Върни индекса на откритата съвпадаща двойна дума MIPS LISTING srch128.s page 1 1 # Да се напише подпрограма, която да връща в регистър $2 индекса на подадената 2 # в регистри $4:$5 двойна дума в масива от двойни думи (BE) с начален адрес в 3 # регистър $7 и брой елементи в регистър $6, или -1, ако не е намерена. 4 5 .ent srch128 6 .global srch128 7 srch128: 8 0000 2402FFFF LI $2,-1 # Инициализирай индекса 9 0004 64420001 L1: DADDIU $2,$2,1 # Актуализирай го 10 0008 1046000A 00000000 BEQ $2,$6,L2 # Всички елементи вече са претърсени? Върни -1 11 0010 00025138 DSLL $10,$2,4 # Превърни индекса в адресно отместване 12 0014 0147502D DADDU $10,$10,$7 # и го добави към началния адрес на масива 13 0018 DD480008 LD $8,8($10) # Зареди следващата двойна дума - първо младшата, 14 LD $9,0($10) # а после и старшата 15 001c 14A8FFF9 DD490000 BNE $5,$8,L1 # Не съвпадат младшите думи? Виж следващия елемент 16 0024 1489FFF7 00000000 BNE $4,$9,L1 # Не съвпадат старшите " " " " " " " 17 002c 03E00008 00000000 JR $31 # Да, върни индекса на намерения съвпадащ " " 18 L2: LI $2,-1 # Двойната дума в $4:$5 не е намерена - 19 0034 03E00008 2402FFFF JR $31 # върни -1 20 003c 00000000 .end srch128 RISC-V LISTING srch128.s page 1 1 # Да се напише подпрограма, която да връща в регистър a0 индекса на подадената 2 # в регистри a1:a0 двойна дума в масива от двойни думи (LE) с начален адрес в 3 # регистър a3 и брой елементи в регистър a2, или -1, ако не е намерена. 4 5 .global srch128 6 srch128: 7 0000 9308F0FF LI a7,-1 # Инициализирай индекса 8 0004 93881800 L1: ADDI a7,a7,1 # Актуализирай го 9 0008 6382C802 BEQ a7,a2,L2 # Всички елементи вече са претърсени? Върни -1 10 000c 13984800 SLLI a6,a7,4 # Превърни индекса в адресно отместване 11 0010 3308D800 ADD a6,a6,a3 # и го добави към началния адрес на масива 12 0014 03370800 LD a4,0(a6) # Зареди следващата двойна дума - първо младшата, 13 0018 83378800 LD a5,8(a6) # а после и старшата 14 001c E314E5FE BNE a0,a4,L1 # Не съвпадат младшите думи? Виж следващия елемент 15 0020 E392F5FE BNE a1,a5,L1 # Не съвпадат старшите " " " " " " " 16 0024 13850800 MV a0,a7 # Да, върни индекса на намерения съвпадащ " " 17 0028 67800000 RET 18 002c 1305F0FF L2: LI a0,-1 # Двойната дума в a1:a0 не е намерена - 19 0030 67800000 RET # върни -1 LOONGARCH64 GAS srch128.s page 1 1 # Да се напише подпрограма, която да връща в регистър r4 индекса на подадената 2 # в регистри r5:r4 двойна дума в масива от двойни думи (LE) с начален адрес в 3 # регистър r7 и брой елементи в регистър r6, или -1, ако не е намерена. 4 5 .global srch128 6 srch128: 7 0000 0B001400 NOR $r11,$r0,$r0 # Инициализирай индекса 8 0004 6B05C002 L1: ADDI.D $r11,$r11,1 # Актуализирай го 9 0008 66210058 BEQ $r11,$r6,L2 # Всички елементи вече са претърсени? Върни -1 10 000c 6A9D2D00 ALSL.D $r10,$r11,$r7,4# Добави мащабирания индекс към началния адрес 11 0010 4801C028 LD.D $r8,$r10,0 # Зареди следващата двойна дума - първо младшата, 12 0014 4921C028 LD.D $r9,$r10,8 # а после и старшата 13 0018 88ECFF5F BNE $r4,$r8,L1 # Не съвпадат младшите думи? Виж следващия елемент 14 001c A9E8FF5F BNE $r5,$r9,L1 # Не съвпадат старшите " " " " " " " 15 0020 64011500 OR $r4,$r11,$r0 # Да, върни индекса на намерения съвпадащ " " 16 0024 2000004C JIRL $r0,$r1,0 17 0028 04001400 L2: NOR $r4,$r0,$r0 # Двойната дума в r5:r4 не е намерена - 18 002c 2000004C JIRL $r0,$r1,0 # върни -1 # Да се напише подпрограма, която да връща в регистър $0 индекса на подадената # в регистри $17:$16 двойна дума в масива от двойни думи (LE) с начален адрес srch128.o: file format ecoff-littlealpha # в регистър $19 и брой елементи в регистър $18, или -1, ако не е намерена. Disassembly of section .text: .ent srch128 .globl srch128 0000000000000000 : srch128: 0: ff ff 1f 20 lda v0,-1(zero) lda $0,-1($31) # Инициализирай индекса 4: 00 34 00 40 addq v0,0x1,v0 L1: addq $0,1,$0 # Актуализирай го 8: a1 05 12 40 cmpeq v0,a2,t0 cmpeq $0,$18,$1 # Всички елементи вече са претърсени? c: ff ff 9f 23 lda at,-1(zero) 10: c0 04 3c 44 cmovne t0,at,v0 cmovne $1,-1,$0 # Да, върни -1 14: 08 00 20 f4 bne t0,38 bne $1,L2 18: 43 06 13 40 s8addq v0,a3,t2 s8addq $0,$19,$3 # Не, добави мащабирания индекс към началния адрес 1c: 43 06 03 40 s8addq v0,t2,t2 s8addq $0,$3,$3 20: 00 00 23 a4 ldq t0,0(t2) ldq $1,0($3) # Зареди следващата двойна дума - първо младшата, 24: 08 00 43 a4 ldq t1,8(t2) ldq $2,8($3) # а после и старшата 28: a3 05 01 42 cmpeq a0,t0,t2 cmpeq $16,$1,$3 # Съвпадат ли младшите думи? 2c: f5 ff 7f e4 beq t2,4 beq $3,L1 # Не, виж следващия елемент 30: a3 05 22 42 cmpeq a1,t1,t2 cmpeq $17,$2,$3 # Да, съвпадат ли и старшите? 34: f3 ff 7f e4 beq t2,4 beq $3,L1 # Не, виж следващия елемент 38: 01 80 fa 6b ret zero,(ra),0x1 L2: ret # Да, върни индекса на намерения съвпадащ елемент 3c: 1f 04 ff 47 nop .end srch128 GAS for MMIX srch128.s page 1 1 % Да се напише подпрограма, която да връща в регистър $0 индекса на двойната 2 % дума, чийто адрес ѝ е подаден в същия регистър, в масива от двойни думи (BE) 3 % с начален адрес в регистър $2 и брой елементи в регистър $1, или -1, ако не е 4 % намерена. 5 6 .global srch128 7 srch128: 8 0000 8D030000 LDO $3,$0,0 % Зареди старшата 9 0004 8D040008 LDO $4,$0,8 % и младшата дума на търсената двойна дума 10 0008 CE050505 NXOR $5,$5,$5 % Трябва да се върне −1, ако дв. дума не е намерена 11 000c C1000500 OR $0,$5,0 % Инициализирай индекса с −1 12 0010 23000001 L1: ADDU $0,$0,1 % Актуализирай го 13 0014 32060001 CMPU $6,$0,$1 % Всички елементи вече са претърсени? 14 0018 62000605 CSZ $0,$6,$5 % Да, върни −1 15 001c 42060008 BZ $6,L2 16 0020 2E060002 16ADDU $6,$0,$2 % Не, добави мащабирания индекс към началния адрес 17 0024 8F070608 LDOU $7,$6,8 % Зареди следващата двойна дума - първо младшата, 18 0028 8F080600 LDOU $8,$6,0 % а после и старшата 19 002c 30060407 CMP $6,$4,$7 % Съвпадат ли младшите думи? 20 0030 4B06FFF8 BNZ $6,L1 % Не, виж следващия елемент 21 0034 30060308 CMP $6,$3,$8 % Да, съвпадат ли и старшите? 22 0038 4B06FFF6 BNZ $6,L1 % Не, виж следващия елемент 23 003c F8010000 L2: POP 1,0 % Да, върни индекса на намерения съвпадащ елемент HPPA64 LISTING srch128.s page 1 1 ; Да се напише подпрограма, която да връща в регистър %R28 индекса на подадена 2 ; в регистри %R26:%R25 двойна дума в масива от двойни думи (BE) с начален адрес 3 ; в регистър %R23 и брой елементи в регистър %R24, или -1, ако не е намерена. 4 5 .global srch128 6 srch128: 7 0000 341C3FFF LDI -1,%R28 ; Инициализирай индекса 8 0004 B79C0002 L1: ADDI 1,%R28,%R28 ; Актуализирай го 9 0008 BF1C8022 CMPB,*>>=,N %R28,%R24,L2; Всички елементи вече са претърсени? Върни -1 10 000c 0EF010F5 LDD,MA 8(%R23),%R21; Зареди старшата дума (изпълнява се преди „CMPB“!) 11 0010 BEBA3FDD CMPB,*<> %R26,%R21,L1; Не съвпадат старшите думи? Виж следващия елемент 12 0014 0EF010F6 LDD,MA 8(%R23),%R22; Зареди младшата дума (изпълнява се преди „CMPB“!) 13 0018 BED93FCD CMPB,*<> %R25,%R22,L1; Не съвпадат младшите думи? Виж следващия елемент 14 001c 0AD92880 CMPCLR,= %R25,%R22,%R0;Съвпадение: върни индекса (изп.се преди „CMPB“!) 15 0020 341C3FFF L2: LDI -1,%R28 ; Двойната дума не е намерена: върни -1 16 0024 E840D002 BVE,N (%R2) TILE-Gx GAS srch128.s page 1 1 # Да се напише подпрограма, която да връща в регистър r4 индекса на подадената 2 # в регистри r1:r0 двойна дума в масива от двойни думи (LE) с начален адрес 3 # в регистър r3 и брой елементи в регистър r2, или -1, ако не е намерена. 4 5 .global srch128 6 srch128: 7 { MOVEI r8,-1 # Подготви стойността за връщане при ненамиране 8 0000 C8FF1F40 E2FF0F18 MOVEI r4,-1 } # Инициализирай индекса 9 0008 00304851 82080818 L1: ADDI r4,r4,1 # Актуализирай го 10 0010 003048D1 82100A28 CMPEQ r5,r4,r2 # Всички елементи вече са претърсени? 11 { CMOVNEZ r4,r5,r8 # Да, върни -1 12 0018 448118D0 A300C017 BNEZ r5,L2 } 13 0020 003048D1 83184828 SHL3ADD r7,r4,r3 # Не, добави мащабирания индекс към началния адрес 14 0028 003048D1 83384828 SHL3ADD r7,r4,r7 15 0030 003048D1 E240A018 LD_ADD r5,r7,8 # Зареди следващата двойна дума - първо младшата, 16 { LD r6,r7 # а после и старшата 17 0038 07507044 0040369E CMPEQ r7,r0,r5 } # Съвпадат ли младшите думи? 18 { BEQZT r7,L1 # Не, виж следващия елемент 19 0040 47601CD0 FCF83F14 CMPEQ r7,r1,r6 } # Да, съвпадат ли и старшите? 20 0048 00304851 FCF83F14 BEQZT r7,L1 # Не, виж следващия елемент 21 L2: { MOVE r0,r4 # Да, върни индекса на намерения съвпадащ елемент 22 0050 00F10751 E0766A28 JR lr } IA-64 GAS srch128.s page 1 1 // Да се напише подпрограма, която да връща в регистър r8 индекса на подадената 2 // в регистри in1:in0 двойна дума в масива от двойни думи (LE) с начален адрес 3 // в регистър in3 и брой елементи в регистър in2, или -1, ако не е намерена. 4 5 .global srch128 6 srch128: 7 ALLOC loc3=ar.pfs,4,4,0,0 8 MOV r8=-1 // Инициализирай индекса 9 L1: ADD r8=r8,r0,1 // Актуализирай го 10 0000 01382110 800580F8 F3FF4F00 00000400 CMP.EQ p6,p7=r8,in2 // Всички елементи вече са претърсени? 11 (p6) MOV r8=-1 // Да, върни -1 12 0010 0B402000 01206040 880E7000 00000400 (p6) BR.RET.SPTK rp 13 SHLADD loc2=r8,4,in3// Не, събери мащабирания индекс с началния адрес 14 0020 D040FCF9 FF270000 00020083 00008400 LD8 loc0=[loc2],8// Зареди следващата двойна дума - първо младшата, 15 LD8 loc1=[loc2] // а после и старшата 16 0030 0B302146 13204042 98302800 00000400 CMP.EQ p6,p7=in0,loc0//Съвпадат ли младшите думи? 17 (p6) CMP.EQ p6,p7=in1,loc1//Да, съвпадат ли и старшите? 18 0040 0228014C 18106000 910E70C3 102A1DE0 (p7) BR L1 // Не, виж следващия елемент 19 0050 13000000 01C001E0 FF7F2480 00008400 BR.RET.SPTK rp // Да, върни индекса на намерения съвпадащ елемент E2K GAS srch128.s page 1 1 ! Да се напише подпрограма, която да връща в регистър r0 индекса на подадената 2 ! в регистри r1:r0 двойна дума в масива от двойни думи (LE) с начален адрес 3 ! в регистър r3 и брой елементи в регистър r2, или -1, ако не е намерена. 4 5 .global srch128 6 srch128: 7 { setwd wsz=8,nfx=1 ! wsz = брой използвани регистри, nfx = неясно! 8 0000 12C00000 04000040 00000000 10010000 disp %ctpr1,L1 } ! Подготви прехода към началото на цикъла 9 { return %ctpr3 ! и връщането към извикващата функция 10 0010 12400004 87D4C005 000000F0 0000FFFF ord 0,-1,%r7 } ! Инициализирай индекса 11 0020 01000004 87C18711 L1: addd %r7,1,%r7 ! Всички ли елементи вече са претърсени? 12 0028 01010004 40828721 cmpedb %r7,%r2,%pred0! (актуализирай индекса) 13 { ord 0,-1,%r0 ? %pred0! Да, върни -1 14 0030 22100104 400C00C0 80D4C005 00000000 0000FFFF 00006004 ct %ctpr3 ? %pred0 } 15 0048 11002008 86C48719 0000830A 00000000 shl_addd %r7,4,%r3,%r6! Не, събери мащабирания индекс с началния адрес 16 { ldd [%r6+8],%r5 ! Зареди следващата двойна дума - първо старшата, 17 0058 12000014 85C88667 84C08667 00000000 ldd [%r6+0],%r4 } ! а после и младшата 18 0068 01010004 40858121 cmpedb %r1,%r5,%pred0! Съвпадат ли старшите думи? 19 0070 11010104 40848021 00000000 00006004 cmpedb %r0,%r4,%pred0 ? %pred0! Да, съвпадат ли и младшите? 20 0080 01100000 600400C0 ct %ctpr1 ? ~%pred0! Не, виж следващия елемент 21 { ord %r7,0,%r0 ! Да, върни индекса на намерения съвпадащ елемент 22 0088 12100004 200C00C0 80C08705 00000000 ct %ctpr3 } S/390x LISTING binsrch.s page 1 1 # Да се напише подпрограма, която да връща в регистър 2 индекса на подадената 2 # пак там дума в сортирания във възходящ ред масив от думи със знак с начален 3 # адрес и брой елементи съответно в регистри 3 и 4, а ако не е намерена, -1. 4 5 #int binarySearch(int t, int *x, unsigned n)/* Из книгата "Бисери на програ- */ 6 #{ /* мирането" от Джон Луис Бентли */ 7 # unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 # while (l <= u) { 9 # m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 # if (x[m] < t) 11 # l = m + 1; 12 # else if (x[m] == t) 13 # return m; 14 # else /* x[m] > t */ 15 # u = m - 1; 16 # } 17 # return -1; 18 #} 19 20 # Търсената дума t е 2, масивът x е 3, размерът n е 4 (по условие); 21 # долният индекс l е 5, горният u е 6, средният m е 7 (по избор). 22 23 .global binsrch 24 binsrch: 25 0000 EB67F010 0024 STMG 6,7,16(15) # Съхрани използваните регистри (LNUX-1007-02) 26 0006 B9820055 XGR 5,5 # l = 0; 27 000a EC64FFFF 00D9 AGHIK 6,4,-1 # u = n - 1; 28 0010 EC560021 2065 L1: CLGRJH 5,6,L4 # while (l <= u) { 29 0016 41756000 LA 7,0(5,6) # m = (l + u) 30 001a EB770001 000C SRLG 7,7,1 # / 2; // l и u < 2^61 31 0020 B9040017 LGR 1,7 # Превърни индекса в адресно отместване 32 0024 EB110003 000D SLLG 1,1,3 33 002a E3231000 0020 CG 2,0(3,1) # if (x[m] < t) 34 0030 A7D40006 JNH L2 35 0034 41507001 LA 5,1(7) # l = m + 1; 36 0038 A7F4FFEC J L1 37 003c A7740006 L2: JNE L3 38 0040 B9040027 LGR 2,7 # else if (x[m] == t) 39 0044 A7F40009 J L5 # return m; 40 0048 EC67FFFF 00D9 L3: AGHIK 6,7,-1 # else /* x[m] > t */ u = m - 1; 41 004e A7F4FFE1 J L1 # } 42 0052 A729FFFF L4: LGHI 2,-1 # return -1; 43 0056 EB67F010 0004 L5: LMG 6,7,16(15) # Възстанови съхранените регистри 44 005c 07FE0707 BR 14 # Върни управлението AMD64 GAS binsrch.s page 1 1 # Да се напише подпрограма, която да връща в регистър EAX индекса на подадената 2 # в RDI дума в сортирания във възходящ ред масив от думи със знак с начален 3 # адрес и брой елементи съответно в RSI и RDX, а ако не е намерена, -1. 4 5 #int binarySearch(int t, int *x, unsigned n)/* Из книгата "Бисери на програ- */ 6 #{ /* мирането" от Джон Луис Бентли */ 7 # unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 # while (l <= u) { 9 # m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 # if (x[m] < t) 11 # l = m + 1; 12 # else if (x[m] == t) 13 # return m; 14 # else /* x[m] > t */ 15 # u = m - 1; 16 # } 17 # return -1; 18 #} 19 20 # Търсената дума t е в RDI, адресът на масива x е в RSI, размерът n в RDX; 21 # долният индекс l е в RCX, горният u е в RDX, а средният m е в RAX (по избор). 22 23 .intel_syntax noprefix 24 .global binsrch 25 binsrch: 26 0000 4831C9 XOR RCX,RCX # l = 0; 27 0003 48FFCA DEC RDX # u = n - 1; 28 0006 4839CA L1: CMP RDX,RCX 29 0009 721B JB L3 # while (l <= u) { 30 000b 488D040A LEA RAX,[RDX+RCX] # m = (l + u) 31 000f 48D1E8 SHR RAX,1 # / 2; // без знак 32 0012 48393CC6 CMP [RSI+8*RAX],RDI 33 0016 7D06 JGE L2 # if (x[m] < t) 34 0018 488D4801 LEA RCX,[RAX+1] # l = m + 1; 35 001c EBE8 JMP L1 # ___ else if (x[m] == t) 36 001e 7409 L2: JE L4 #__/ return m; 37 0020 488D50FF LEA RDX,[RAX-1] # else /* x[m] > t */ u = m - 1; 38 0024 EBE0 JMP L1 # } 39 0026 4819C0 L3: SBB RAX,RAX # return -1; 40 0029 C3 L4: RET AARCH64 GAS binsrch.s page 1 1 // Да се напише подпрограма, която да връща в регистър X0 индекса на подадената 2 // пак там дума в сортирания във възходящ ред масив от думи със знак с начален 3 // адрес и брой елементи съответно в регистри X1 и X2, а ако не е намерена, -1. 4 5 //int binarySearch(int t, int *x, unsigned n)/* Из книгата "Бисери на програ-*/ 6 //{ /* мирането" от Джон Луис Бентли */ 7 // unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 // while (l <= u) { 9 // m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 // if (x[m] < t) 11 // l = m + 1; 12 // else if (x[m] == t) 13 // return m; 14 // else /* x[m] > t */ 15 // u = m - 1; 16 // } 17 // return -1; 18 //} 19 20 // Търсената дума t е X0, масивът x е X1, размерът n е X2 (по условие); 21 // долният индекс l е X3, горният u е X4, средният m е X5 (по избор). 22 23 .global binsrch 24 binsrch: 25 0000 E3031FAA MOV X3,XZR // l = 0; 26 0004 440400D1 SUB X4,X2,#1 // u = n - 1; 27 0008 7F0004EB L1: CMP X3,X4 28 000c 48010054 BHI L2 // while (l <= u) { 29 0010 6500048B ADD X5,X3,X4 // m = (l + u) 30 0014 A5FC41D3 LSR X5,X5,#1 // / 2; // l и u < 2^60 31 0018 267865F8 LDR X6,[X1,X5,LSL #3] 32 001c DF0000EB CMP X6,X0 // if (x[m] < t) 33 0020 63A4859A CSINC X3,X3,X5,GE // l = m + 1; 34 0024 2BFFFF54 BLT L1 35 0028 60000054 BEQ L2 // else if (x[m] == t) return m; 36 002c A40400D1 SUB X4,X5,#1 // else /* x[m] > t */ u = m - 1; 37 0030 F6FFFF17 B L1 // } 38 0034 A0009FDA L2: CSINV X0,X5,XZR,EQ // return -1; 39 0038 C0035FD6 RET // Върни управлението ARC GAS binsrch.s page 1 1 # Да се напише подпрограма, която да връща в регистър r0 индекса на подадената 2 # пак там дума в сортирания във възходящ ред масив от думи със знак с начален 3 # адрес и брой елементи съответно в регистри r1 и r2, а ако не е намерена, -1. 4 5 #int binarySearch(int t, int *x, unsigned n)/* Из книгата "Бисери на програ-*/ 6 #{ /* мирането" от Джон Луис Бентли */ 7 # unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 # while (l <= u) { 9 # m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 # if (x[m] < t) 11 # l = m + 1; 12 # else if (x[m] == t) 13 # return m; 14 # else /* x[m] > t */ 15 # u = m - 1; 16 # } 17 # return -1; 18 #} 19 20 # Търсената дума t е r0, масивът x е r1, размерът n е r2 (по условие); 21 # долният индекс l е r3, горният u е r4, средният m е r5 (по избор). 22 23 .align 4 # Избегни грешно генерирано отместване на „BL“! 24 .global binsrch 25 binsrch: 26 0000 00DB MOVL_S r3,0 # l = 0; 27 0002 425A 4400 SUBL r4,r2,1 # u = n - 1; 28 0006 270C CC00 L1: BRLOL r4,r3,L3 # while (l <= u) { 29 000a 005B 0501 ADDL r5,r3,r4 # m = (l + u) 30 000e 615D 4500 LSRL r5,r5,1 # / 2;// l,u < 2^63 31 0012 F121 4681 LDL.AS r6,[r1,r5] 32 0016 0D0E 0B00 BRGEL r6,r0,L2 # if (x[m] < t) 33 001a 405D 4300 ADDL r3,r5,1 # l = m + 1; 34 001e F5F1 B_S L1 35 0020 0F0E 0800 L2: BREQL r6,r0,L4 # else if (x[m] == t) return m; 36 0024 425D 4400 SUBL r4,r5,1 # else /* x[m] > t */ u = m - 1; 37 0028 EFF1 B_S L1 # } 38 002a 6F5D 0A00 L3: NOTL r5,0 # return -1; 39 002e A440 L4: MOVL_S r0,r5 40 0030 E07E E078 J_S [blink] # Върни управлението PPC LISTING binsrch.s page 1 1 # Да се напише подпрограма, която да връща в регистър r3 индекса на подадената 2 # пак там дума в сортирания във възходящ ред масив от думи със знак с начален 3 # адрес и брой елементи съответно в регистри r4 и r5, а ако не е намерена, -1. 4 5 #int binarySearch(int t, int *x, unsigned n)/* Из книгата "Бисери на програ- */ 6 #{ /* мирането" от Джон Луис Бентли */ 7 # unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 # while (l <= u) { 9 # m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 # if (x[m] < t) 11 # l = m + 1; 12 # else if (x[m] == t) 13 # return m; 14 # else /* x[m] > t */ 15 # u = m - 1; 16 # } 17 # return -1; 18 #} 19 20 # Търсената дума t е r3, масивът x е r4, размерът n е r5 (по условие); 21 # долният индекс l е r6, горният u е r7, средният m е r8 (по избор). 22 23 .global binsrch 24 binsrch: 25 0000 38C00000 li r6,0 # l = 0; 26 0004 38E5FFFF addi r7,r5,-1 # u = n - 1; 27 0008 7C263840 L1: cmpld r6,r7 28 000c 41810038 bgt L4 # while (l <= u) { 29 0010 7D063A14 add r8,r6,r7 # m = (l + u) 30 0014 7908F842 srdi r8,r8,1 # / 2; // l и u < 2^30 31 0018 790A1F24 sldi r10,r8,3 # Превърни индекса в адресно отместване 32 001c 7D24502A ldx r9,r4,r10 33 0020 7C291800 cmpd r9,r3 # if (x[m] < t) 34 0024 4080000C bge L2 35 0028 38C80001 addi r6,r8,1 # l = m + 1; 36 002c 4BFFFFDC b L1 37 0030 4082000C L2: bne L3 38 0034 7D034378 mr r3,r8 # else if (x[m] == t) 39 0038 4E800020 blr # return m; 40 003c 38E8FFFF L3: addi r7,r8,-1 # else /* x[m] > t */ u = m - 1; 41 0040 4BFFFFC8 b L1 # } 42 0044 3860FFFF L4: li r3,-1 # return -1; 43 0048 4E800020 blr # Върни управлението SPARC GAS binsrch.s page 1 1 ! Да се напише подпрограма, която да връща в регистър %o0 индекса на подадената 2 ! пак там дума в сортирания във възходящ ред масив от думи със знак с начален 3 ! адрес и брой елементи съответно в регистри %o1 и %o2, а ако не е намерена, -1 4 5 !int binarySearch(int t, int *x, unsigned n)/* Из книгата "Бисери на програ- */ 6 !{ /* мирането" от Джон Луис Бентли */ 7 ! unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 ! while (l <= u) { 9 ! m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 ! if (x[m] < t) 11 ! l = m + 1; 12 ! else if (x[m] == t) 13 ! return m; 14 ! else /* x[m] > t */ 15 ! u = m - 1; 16 ! } 17 ! return -1; 18 !} 19 20 ! Търсената дума t е %o0, масивът x е %o1, размерът n е %o2 (по условие); 21 ! долният индекс l е %o3, горният u е %o4, средният m е %o5 (по избор). 22 23 .global binsrch 24 binsrch: 25 0000 96102000 mov 0,%o3 ! l = 0; 26 0004 9822A001 sub %o2,1,%o4 ! u = n - 1; 27 0008 80A2C00C L1: cmp %o3,%o4 28 000c 18680010 bgu %xcc,L4 ! while (l <= u) { 29 0010 9A02C00C add %o3,%o4,%o5 ! m = (l + u) 30 0014 9B337001 srlx %o5,1,%o5 ! / 2; // l и u < 2^30 31 0018 832B7003 sllx %o5,3,%g1 ! Превърни индекса в адресно отместване 32 001c C25A4001 ldx [%o1+%g1],%g1 33 0020 80A04008 cmp %g1,%o0 ! if (x[m] < t) 34 0024 16680004 bge %xcc,L2 35 0028 01000000 nop 36 002c 10BFFFF7 ba L1 ! След „add“! 37 0030 96036001 add %o5,1,%o3 ! l = m + 1; 38 0034 12680004 L2: bne %xcc,L3 39 0038 01000000 nop 40 003c 81C3E008 retl ! След „mov“! 41 0040 9010000D mov %o5,%o0 ! else if (x[m] == t) return m; 42 0044 10BFFFF1 L3: ba L1 ! След „sub“! 43 0048 98236001 sub %o5,1,%o4 ! else /* x[m] > t */ u = m - 1; 44 004c 81C3E008 L4: retl ! След „mov“! } 45 0050 90103FFF mov -1,%o0 ! return -1; MIPS LISTING binsrch.s page 1 1 # Да се напише подпрограма, която да връща в регистър $2 индекса на подадената 2 # в рег. $4 дума в сортирания във възходящ ред масив от думи със знак с начален 3 # адрес и брой елементи съответно в регистри $5 и $6, а ако не е намерена, -1. 4 5 #int binarySearch(int t, int *x, unsigned n)/* Из книгата "Бисери на програ- */ 6 #{ /* мирането" от Джон Луис Бентли */ 7 # unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 # while (l <= u) { 9 # m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 # if (x[m] < t) 11 # l = m + 1; 12 # else if (x[m] == t) 13 # return m; 14 # else /* x[m] > t */ 15 # u = m - 1; 16 # } 17 # return -1; 18 #} 19 20 # Търсената дума t е $4, масивът x е $5, размерът n е $6 (по условие); 21 # долният индекс l е $7, горният u е $8, средният m е $9 (по избор). 22 23 .ent binsrch 24 .global binsrch 25 binsrch: 26 0000 24070000 LI $7,0 # int l = 0; 27 0004 64C8FFFF DADDIU $8,$6,-1 # int u = n - 1; 28 0008 0107082A 14200011 00000000 L1: BGT $7,$8,L4 # while (l <= u) { // l и u < 2^30 29 0014 00E8482D DADDU $9,$7,$8 # int m = (l + u) 30 0018 0009487A DSRL $9,$9,1 # / 2;// " " " 31 001c 000958F8 DSLL $11,$9,3 # Превърни индекса в адресно отместване 32 0020 0165582D DADDU $11,$11,$5 # и го добави към началния адрес на масива 33 0024 DD6A0000 LD $10,0($11) 34 0028 0144082A 10200003 00000000 BGE $10,$4,L2 # if (x[m] < t) 35 DADDIU $7,$9,1 # l = m + 1; 36 0034 1000FFF4 65270001 B L1 37 003c 15440003 00000000 L2: BNE $10,$4,L3 # else if (x[m] == t) 38 MOVE $2,$9 # return m; 39 0044 03E00008 01201025 JR $31 40 L3: DADDIU $8,$9,-1 # else /* x[m] > t */ u = m - 1; 41 004c 1000FFEE 6528FFFF B L1 # } 42 L4: LI $2,-1 # return -1; 43 0054 03E00008 2402FFFF JR $31 # Върни управлението 44 005c 00000000 .end binsrch RISC-V LISTING binsrch.s page 1 1 # Да се напише подпрограма, която да връща в регистър a0 индекса на подадената 2 # пак там дума в сортирания във възходящ ред масив от думи със знак с начален 3 # адрес и брой елементи съответно в регистри a1 и a2, а ако не е намерена, -1. 4 5 #int binarySearch(int t, int *x, unsigned n)/* Из книгата "Бисери на програ- */ 6 #{ /* мирането" от Джон Луис Бентли */ 7 # unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 # while (l <= u) { 9 # m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 # if (x[m] < t) 11 # l = m + 1; 12 # else if (x[m] == t) 13 # return m; 14 # else /* x[m] > t */ 15 # u = m - 1; 16 # } 17 # return -1; 18 #} 19 20 # Търсената дума t е a0, масивът x е a1, размерът n е a2 (по условие); 21 # долният индекс l е a3, горният u е a4, средният m е a5 (по избор). 22 23 .global binsrch 24 binsrch: 25 0000 93060000 MV a3,x0 # int l = 0; 26 0004 1307F6FF ADDI a4,a2,-1 # int u = n - 1; 27 0008 634CD702 L1: BGT a3,a4,L4 # while (l <= u) { // l и u < 2^30 28 000c B387E600 ADD a5,a3,a4 # int m = (l + u) 29 0010 93D71700 SRLI a5,a5,1 # / 2;// " " " 30 0014 93983700 SLLI a7,a5,3 # Превърни индекса в адресно отместване 31 0018 B388B800 ADD a7,a7,a1 # и го добави към началния адрес на масива 32 001c 03B80800 LD a6,0(a7) 33 0020 6356A800 BGE a6,a0,L2 # if (x[m] < t) 34 0024 93861700 ADDI a3,a5,1 # l = m + 1; 35 0028 6FF01FFE J L1 36 002c 6316A800 L2: BNE a6,a0,L3 # else if (x[m] == t) 37 0030 13850700 MV a0,a5 # return m; 38 0034 67800000 RET 39 0038 1387F7FF L3: ADDI a4,a5,-1 # else /* x[m] > t */ u = m - 1; 40 003c 6FF0DFFC J L1 # } 41 0040 1305F0FF L4: LI a0,-1 # return -1; 42 0044 67800000 RET # Върни управлението LOONGARCH64 GAS binsrch.s page 1 1 # Да се напише подпрограма, която да връща в регистър r4 индекса на подадената 2 # в рег. r4 дума в сортирания във възходящ ред масив от думи със знак с начален 3 # адрес и брой елементи съответно в регистри $r5 и $r6, а ако не е намерена, -1. 4 5 #int binarySearch(int t, int *x, unsigned n)/* Из книгата "Бисери на програ- */ 6 #{ /* мирането" от Джон Луис Бентли */ 7 # unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 # while (l <= u) { 9 # m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 # if (x[m] < t) 11 # l = m + 1; 12 # else if (x[m] == t) 13 # return m; 14 # else /* x[m] > t */ 15 # u = m - 1; 16 # } 17 # return -1; 18 #} 19 20 # Търсената дума t е r4, масивът x е r5, размерът n е r6 (по условие); 21 # долният индекс l е r7, горният u е r8, средният m е r9 (по избор). 22 23 .global binsrch 24 binsrch: 25 0000 07001500 OR $r7,$r0,$r0 # int l = 0; 26 0004 C8FCFF02 ADDI.D $r8,$r6,-1 # int u = n - 1; 27 0008 07350060 L1: BGT $r7,$r8,L4 # while (l <= u) { // l и u < 2^60 28 000c E9A01000 ADD.D $r9,$r7,$r8 # int m = (l + u) 29 0010 29054500 SRLI.D $r9,$r9,1 # / 2;// " " " 30 0014 2B152D00 ALSL.D $r11,$r9,$r5,3 # Добави индекса към началния адрес на масива 31 0018 6A01C028 LD.D $r10,$r11,0 32 001c 440D0064 BGE $r10,$r4,L2 # if (x[m] < t) 33 0020 2705C002 ADDI.D $r7,$r9,1 # l = m + 1; 34 0024 FFE7FF53 B L1 35 0028 440D005C L2: BNE $r10,$r4,L3 # else if (x[m] == t) 36 002c 24011500 OR $r4,$r9,$r0 # return m; 37 0030 2000004C JIRL $r0,$r1,0 38 0034 28FDFF02 L3: ADDI.D $r8,$r9,-1 # else /* x[m] > t */ u = m - 1; 39 0038 FFD3FF53 B L1 # } 40 003c 04001400 L4: NOR $r4,$r0,$r0 # return -1; 41 0040 2000004C JIRL $r0,$r1,0 # Върни управлението # Да се напише подпрограма, която да връща в рег. $0 индекса на подадената в # рег. $16 дума в сортирания във възходящ ред масив от думи със знак с начален # адрес и брой елементи съответно в регистри $17 и $18, а ако не я намери, -1. #int binarySearch(int t, int *x, unsigned n)/*Из книгата "Бисери на програ- */ #{ /* мирането" от Джон Луис Бентли */ # unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ # while (l <= u) { # m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ # if (x[m] < t) # l = m + 1; # else if (x[m] == t) # return m; # else /* x[m] > t */ # u = m - 1; # } # return -1; #} # Търсената дума t е $16, масивът x е $17, размерът n е $18 (по условие); binsrch.o: file format ecoff-littlealpha # долният индекс l е $1, горният u е $2, средният m е $0 (по избор). Disassembly of section .text: .ent binsrch .globl binsrch 0000000000000000 : binsrch: 0: 01 04 ff 47 clr t0 bis $31,$31,$1 # int l = 0; 4: 22 35 40 42 subq a2,0x1,t1 subq $18,1,$2 # int u = n - 1; 8: a3 0d 22 40 cmple t0,t1,t2 L1: cmple $1,$2,$3 # while (l <= u) { // l и u < 2^60 c: ff ff 9f 23 lda at,-1(zero) 10: 80 04 7c 44 cmoveq t2,at,v0 cmoveq $3,-1,$0 #_ 14: 0a 00 60 e4 beq t2,40 beq $3,L3 # \ 18: 00 04 22 40 addq t0,t1,v0 addq $1,$2,$0 # | int m = (l + u) 1c: 80 36 00 48 srl v0,0x1,v0 srl $0,1,$0 # | / 2;// " " " 20: 43 06 11 40 s8addq v0,a1,t2 s8addq $0,$17,$3 # |Добави индекса към началния адрес на масива 24: 00 00 83 a4 ldq t3,0(t2) ldq $4,0($3) # | 28: a3 09 90 40 cmplt t3,a0,t2 cmplt $4,$16,$3 # | if (x[m] < t) 2c: 02 00 60 e4 beq t2,38 beq $3,L2 # | 30: 01 34 00 40 addq v0,0x1,t0 addq $0,1,$1 # | l = m + 1; 34: f4 ff ff c3 br 8 br $31,L1 # | 38: a3 05 90 40 cmpeq t3,a0,t2 L2: cmpeq $4,$16,$3 # | else if (x[m] == t) 3c: 01 00 60 e4 beq t2,44 beq $3,L4 # | 40: 01 80 fa 6b ret zero,(ra),0x1 L3: ret # | return m; 44: 22 35 00 40 subq v0,0x1,t1 L4: subq $0,1,$2 # \ else /* x[m] > t */ u = m - 1; 48: ef ff ff c3 br 8 br $31,L1 # } return -1; 4c: 1f 04 ff 47 nop .end binsrch GAS for MMIX binsrch.s page 1 1 % Да се напише подпрограма, която да връща в рег. $0 индекса на подадената в 2 % същия регистър дума в сортирания във възходящ ред масив от думи със знак с 3 % начален адрес и брой елементи съответно в рег.$1 и $2, а ако не я намери, -1. 4 5 %int binarySearch(int t, int *x, unsigned n)/*Из книгата "Бисери на програ- */ 6 %{ /* мирането" от Джон Луис Бентли */ 7 % unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 % while (l <= u) { 9 % m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 % if (x[m] < t) 11 % l = m + 1; 12 % else if (x[m] == t) 13 % return m; 14 % else /* x[m] > t */ 15 % u = m - 1; 16 % } 17 % return -1; 18 %} 19 20 % Търсената дума t е $0, масивът x е $1, размерът n е $2 (по условие); 21 % долният индекс l е $3, горният u е $4, средният m е $5 (по избор). 22 23 .global binsrch 24 binsrch: 25 0000 C6030303 XOR $3,$3,$3 % int l = 0; 26 0004 27040201 SUBU $4,$2,1 % int u = n - 1; 27 0008 CE070707 NXOR $7,$7,$7 % −1 28 000c 32060304 L1: CMPU $6,$3,$4 % while (l <= u) { // l и u < 2^60 29 0010 64000607 CSP $0,$6,$7 %_ 30 0014 4406000B BP $6,L3 % \ 31 0018 22050304 ADDU $5,$3,$4 % | int m = (l + u) 32 001c 3F050501 SRU $5,$5,1 % | / 2;// " " " 33 0020 2C060501 8ADDU $6,$5,$1 % |Добави индекса към началния адрес на масива 34 0024 8D080600 LDO $8,$6,0 % | 35 0028 30060800 CMP $6,$8,$0 % | if (x[m] < t) 36 002c 48060003 BNN $6,L2 % | 37 0030 23030501 ADDU $3,$5,1 % | l = m + 1; 38 0034 F1FFFFF6 JMP L1 % | 39 0038 4A060003 L2: BNZ $6,L4 % | else if (x[m] == t) 40 003c C1000500 OR $0,$5,0 % | 41 0040 F8010000 L3: POP 1,0 % | return m; 42 0044 27040501 L4: SUBU $4,$5,1 % \ else /* x[m] > t */ u = m - 1; 43 0048 F1FFFFF1 JMP L1 % } return -1; HPPA64 LISTING binsrch.s page 1 1 ; Да се напише подпрограма, която да връща в регистър %R28 индекса на подадена 2 ; в %R26 дума в сортирания във възходящ ред масив от думи със знак с начален 3 ; адрес и брой елементи съответно в %R25 и %R24, а ако не е намерена, -1. 4 5 ;int binarySearch(int t, int *x, unsigned n)/* Из книгата "Бисери на програ-*/ 6 ;{ /* мирането" от Джон Луис Бентли */ 7 ; unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 ; while (l <= u) { 9 ; m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 ; if (x[m] < t) 11 ; l = m + 1; 12 ; else if (x[m] == t) 13 ; return m; 14 ; else /* x[m] > t */ 15 ; u = m - 1; 16 ; } 17 ; return -1; 18 ;} 19 20 ; Търсената дума t е %R26, масивът x е %R25, размерът n е %R24 по условие; 21 ; долният индекс l е %R22, горният u е %R23, средният m е %2R8 (по избор). 22 23 .global binsrch 24 binsrch: 25 0000 34160000 LDI 0,%R22 ; l = 0; 26 0004 B71707FF ADDI -1,%R24,%R23 ; u = n - 1; 27 0008 9EF6A00A L1: CMPB,*<<=,N %R22,%R23,L3; while (l <= u) { 28 000c 341C3FFF LDI -1,%R28 ;___ 29 0010 E840D002 L2: BVE,N (%R2) ; | 30 0014 0AF6061C L3: ADD %R22,%R23,%R28 ; | m = (l + u) 31 0018 D3800FDC SHRPD %R0,%R28,1,%R28 ; | / 2; 32 001c 0F3C20D5 LDD,S %R28(%R25),%R21 ; | if (x[m] < t) 33 0020 9F553FD5 CMPB,*= %R21,%R26,L2 ;__ | 34 0024 0B5578A0 CMPCLR,*> %R21,%R26,%R0 ; \| 35 0028 B7960002 ADDI 1,%R28,%R22 ; | l = m + 1; 36 002c 0B5548A0 CMPCLR,*< %R21,%R26,%R0 ; |\_ else if (x[m] == t) return m; 37 0030 B79707FF ADDI -1,%R28,%R23 ; V else /* x[m] > t */ u = m - 1; 38 0034 E81F1F9F B,N L1 ; } return -1; TILE-Gx GAS binsrch.s page 1 1 # Да се напише подпрограма, която да връща в рег. r3 индекса на подадената в 2 # рег. r0 дума в сортирания във възходящ ред масив от думи със знак с начален 3 # адрес и брой елементи съответно в регистри r1 и r2, а ако не я намери, -1. 4 5 #int binarySearch(int t, int *x, unsigned n)/*Из книгата "Бисери на програ- */ 6 #{ /* мирането" от Джон Луис Бентли */ 7 # unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 # while (l <= u) { 9 # m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 # if (x[m] < t) 11 # l = m + 1; 12 # else if (x[m] == t) 13 # return m; 14 # else /* x[m] > t */ 15 # u = m - 1; 16 # } 17 # return -1; 18 #} 19 20 # Търсената дума t е r0, масивът x е r1, размерът n е r2 (по условие); 21 # долният индекс l е r4, горният u е r5, средният m е r3 (по избор). 22 23 .global binsrch 24 binsrch: 25 { MOVEI r8,-1 # Подготви стойността за връщане при ненамиране 26 0000 C8FF1F40 E2FF3B28 MOVE r4,zero } # int l = 0; 27 0008 003048D1 42F80F18 ADDI r5,r2,-1 # int u = n - 1; 28 0010 00304851 83281028 L1: CMPLES r6,r4,r5 # while (l <= u) { // l и u < 2^60 29 { CMOVEQZ r3,r6,r8 #_ 30 0018 83811450 C5004014 BEQZ r6,L3 } # \ 31 0020 003048D1 81280628 ADD r3,r4,r5 # | int m = (l + u) 32 0028 003048D1 61080A30 SHRUI r3,r3,1 # | / 2;// " " " 33 0030 00304851 63084828 SHL3ADD r6,r3,r1 # |Добави индекса към началния адрес на масива 34 0038 00306C34 00403E9E LD r7,r6 # | 35 0040 00304851 E3001428 CMPLTS r6,r7,r0 # | if (x[m] < t) 36 0048 00304851 C1004014 BEQZ r6,L2 # | 37 { ADDI r4,r3,1 # | l = m + 1; 38 0050 C4101040 FCFFFF27 J L1 } # | 39 0058 00304851 E3000A28 L2: CMPEQ r6,r7,r0 # | else if (x[m] == t) 40 0060 00304851 C1000014 BEQZT r6,L4 # | 41 L3: { MOVE r0,r3 # | return m; 42 0068 C0F00751 E0766A28 JR lr } # | 43 L4: { ADDI r5,r3,-1 # \ else /* x[m] > t */ u = m - 1; 44 0070 C5F01F40 FAFFFF27 J L1 } # } return -1; IA-64 GAS binsrch.s page 1 1 // Да се напише подпрограма, която да връща в рег. r8 индекса на подадената в 2 // рег. in0 дума в сортирания във възходящ ред масив от думи със знак с начален 3 // адрес и брой елементи съответно в регистри in1 и in2, а ако не я намери, -1. 4 5 //int binarySearch(int t, int *x, unsigned n)/*Из книгата "Бисери на програ- */ 6 //{ /* мирането" от Джон Луис Бентли */ 7 // unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 // while (l <= u) { 9 // m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 // if (x[m] < t) 11 // l = m + 1; 12 // else if (x[m] == t) 13 // return m; 14 // else /* x[m] > t */ 15 // u = m - 1; 16 // } 17 // return -1; 18 //} 19 20 // Търсената дума t е in0, масивът x е in1, размерът n е in2 (по условие); 21 // долният индекс l е loc1, горният u е loc2, средният m е r8 (по избор). 22 23 .global binsrch 24 binsrch: 25 ALLOC loc0=ar.pfs,3,4,0,0 26 MOV loc1=r0 // l = 0; 27 SUB loc2=in2,r0,1 // u = n - 1; 28 0000 01181D0E 80054002 000042A0 24021080 L1: CMP.LEU p6,p7=loc1,loc2 // while (l <= u) { 29 (p7) MOV r8=-1 //_ 30 (p7) BR.RET.SPTK rp // \ 31 0010 0A389448 06F481F8 F3FF4F00 00000400 ADD r8=loc1,loc2 // | int m = (l + u) 32 SHR.U r8=r8,1 // | / 2; // l,u < 2^63 33 0020 10000000 01000000 00028083 00008400 SHLADD loc3=r8,3,in1 // |Събери индекса с началния адрес на масива 34 0030 0B40904A 00200000 00020000 2140F852 LD8 loc3=[loc3] // | 35 CMP.LT p6,p7=loc3,in0 // | if (x[m] < t) 36 0040 0B302142 12206002 98302000 00000400 (p6) ADD loc1=r8,r0,1 // | l = m + 1; 37 (p6) BR L1 // | 38 0050 0A309840 07B04142 00024000 00000400 CMP.EQ p6,p7=loc3,in0 // | else if (x[m] == t) 39 (p6) BR.RET.SPTK rp // | return m; 40 0060 10000000 01000000 00020003 B0FFFF48 SUB loc2=r8,r0,1 // \ else /* x[m] > t */ u = m - 1; 41 0070 10309840 07380000 00020083 00008400 BR L1 // } return -1; 41 11282100 04200000 00020000 90FFFF48 E2K GAS binsrch.s page 1 1 ! Да се напише подпрограма, която да връща в регистър r0 индекса на подадената 2 ! пак там дума в сортирания във възходящ ред масив от думи със знак с начален 3 ! адрес и брой елементи съответно в регистри r1 и r2, а ако не я намери, -1. 4 5 !int binarySearch(int t, int *x, unsigned n)/* Из книгата "Бисери на програ- */ 6 !{ /* мирането" от Джон Луис Бентли */ 7 ! unsigned l = 0, u = n - 1, m; /* (там n, l, u и m са тип int). */ 8 ! while (l <= u) { 9 ! m = (l + u) / 2; /* Опасност от препълване (JDK-5045582)! */ 10 ! if (x[m] < t) 11 ! l = m + 1; 12 ! else if (x[m] == t) 13 ! return m; 14 ! else /* x[m] > t */ 15 ! u = m - 1; 16 ! } 17 ! return -1; 18 !} 19 20 ! Търсената дума t е r0, масивът x е r1, размерът n е r2 (по условие); 21 ! долният индекс l е r3, горният u е r4, средният m е r5 (по избор). 22 23 .global binsrch 24 binsrch: 25 { setwd wsz=7,nfx=1 ! wsz = брой използвани регистри, nfx = неясно! 26 0000 12C00000 000000F0 00000000 F0000000 return %ctpr3 } ! Подготви връщането към извикващата функция 27 { disp %ctpr1,L1 ! и прехода към началото на цикъла 28 xord %r3,%r3,%r3 ! l = 0; 29 0010 1340000C 83838309 84C18213 02000040 subd %r2,1,%r4 } ! u = n - 1; 30 0020 01010004 60848321 L1: cmpbedb %r3,%r4,%pred0 ! while (l <= u) { 31 { ord 0,-1,%r0 ? ~%pred0 32 ct %ctpr3 ? ~%pred0! \ 33 0028 2310010C 600C00C0 80D4C005 85848311 0000FFFF 0000E004 addd %r3,%r4,%r5 } ! | int m = (l + u) 34 0040 01000004 85C1851B shrd %r5,1,%r5 ! | / 2; // l,u < 2^63 35 0048 11002008 86C38519 0000810A 00000000 shl_addd %r5,3,%r1,%r6 ! |Събери индекса с началния адрес на масива 36 0058 01000004 86C08667 ldd [%r6],%r6 ! | 37 0060 01010004 C0808621 cmpldb %r6,%r0,%pred0 ! | if (x[m] < t) 38 { addd %r5,1,%r3 ? %pred0!| l = m + 1; 39 ct %ctpr1 ? %pred0 ! | 40 0068 2310010C 400400C0 83C18511 40808621 00000000 00006004 cmpedb %r6,%r0,%pred0 }! | else if (x[m] == t) 41 { ord %r5,0,%r0 ? %pred0!| return m; 42 0080 12100104 400C00C0 80C08505 00006004 ct %ctpr3 ? %pred0}! | 43 { subd %r5,1,%r4 ! \ else /* x[m] > t */ u = m - 1; 44 0090 12100004 200400C0 84C18513 00000000 ct %ctpr1 } ! } return -1; S/390x LISTING inssort.s page 1 1 # Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 # вмъкването масив от думи със знак с начален адрес в регистър 2 и брой 3 # елементи (поне 2) в регистър 3. 4 5 /* void insertionSort(vector& toSort) // Из книгата "Теоретични 6 { // алгоритми на C++" от 7 for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 for (int j = i - 1; j >= 0; --j) 9 if (toSort[j+1] < toSort[j]) 10 swap(toSort[j], toSort[j+1]); 11 else // Тези 2 реда ги няма в 12 break; // горепосочената книга! 13 } */ 14 15 # Нека индексите на външния (i) и вътрешния цикли (j) са регистри 4 и 5. 16 17 .global inssort 18 inssort: 19 0000 A7490001 LGHI 4,1 #for (int i = 1; 20 0004 B9200043 L1: CGR 4,3 # i < toSort.size(); 21 0008 07BE BNLR 14 # Иначе край 22 000a B9040054 LGR 5,4 # for (int j = i 23 000e A75BFFFF L2: AGHI 5,-1 # - 1; --j) 24 0012 A7440019 JL L3 # j >= 0; 25 0016 B9040015 LGR 1,5 26 001a EB110003 000D SLLG 1,1,3 # Превърни индекса в адресно отместване 27 0020 B90A0012 ALGR 1,2 # Получи адреса на toSort[j] 28 0024 E3001008 0004 LG 0,8(1) # if (toSort[j+1] 29 002a E3001000 0020 CG 0,0(1) # < toSort[j]) 30 0030 A7B4000A JNL L3 #_______ 31 0034 D2071008 1000 MVC 8(8,1),0(1)# \ swap(toSort[j], toSort[j+1]); 32 003a E3001000 0024 STG 0,0(1) # \______else break; 33 0040 A7F4FFE7 J L2 # Край на вътрешния цикъл 34 0044 A74B0001 L3: AGHI 4,1 # ++i) 35 0048 A7F4FFDE J L1 # Край на външния цикъл AMD64 GAS inssort.s page 1 1 # Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 # вмъкването масив от думи със знак с начален адрес в регистър RDI и брой 3 # елементи (поне 2) в регистър RSI. 4 5 #void insertionSort(vector& toSort) // Из книгата "Теоретични 6 #{ // алгоритми на C++" от 7 # for (int i = 0; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 # for (int j = i - 1; j >= 0; --j) 9 # if (toSort[j+1] < toSort[j]) 10 # swap(toSort[j], toSort[j+1]); 11 # else // Тези 2 реда ги няма в 12 # break; // горепосочената книга! 13 #} 14 15 # Нека индексът на външния цикъл (i) е RDX, а на вътрешния (j) е RAX. 16 17 .intel_syntax noprefix 18 .global inssort 19 inssort: 20 0000 4831D2 XOR RDX,RDX #for (unsigned i = 0; 21 0003 4839F2 L1: CMP RDX,RSI 22 0006 7323 JAE L4 # i < toSort.size(); 23 0008 4889D0 MOV RAX,RDX # for (unsigned j = i 24 000b 48FFC8 L2: DEC RAX # - 1; --j) 25 000e 7816 JS L3 # DEC не променя CF j != -1; 26 0010 488B4CC7 08 MOV RCX,[RDI+8*RAX+8]# if (toSort[j+1] 27 0015 483B0CC7 CMP RCX,[RDI+8*RAX] # < toSort[j]) 28 0019 7D0B JGE L3 #_________ 29 001b 48870CC7 XCHG RCX,[RDI+8*RAX]# \ swap(toSort[j], toSort[j+1]); 30 001f 48894CC7 08 MOV [RDI+8*RAX+8],RCX# \____else break; 31 0024 EBE5 JMP L2 # Край на вътрешния цикъл 32 0026 48FFC2 L3: INC RDX # ++i) 33 0029 EBD8 JMP L1 # Край на външния цикъл 34 002b C3 L4: RET # Край на подпрограмата AARCH64 GAS inssort.s page 1 1 // Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 // вмъкването масив от думи със знак с начален адрес в регистър X0 и брой 3 // елементи (поне 2) в регистър X1. 4 5 /* void insertionSort(vector& toSort) // Из книгата "Теоретични 6 { // алгоритми на C++" от 7 for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 for (int j = i - 1; j >= 0; --j) 9 if (toSort[j+1] < toSort[j]) 10 swap(toSort[j], toSort[j+1]); 11 else // Тези 2 реда ги няма в 12 break; // горепосочената книга! 13 } */ 14 15 // Нека индексът на външния цикъл (i) е X2, а на вътрешния (j) е X3. 16 17 .global inssort 18 inssort: 19 0000 220080D2 MOV X2,#1 //for (unsigned i = 1; 20 0004 5F0001EB L1: CMP X2,X1 // i < toSort.size(); 21 0008 82010054 BHS L4 22 000c E30302AA MOV X3,X2 // for (unsigned j = i 23 0010 630400F1 L2: SUBS X3,X3,#1// - 1; --j) 24 0014 E3000054 BLO L3 // j != -1; 25 0018 060C038B ADD X6,X0,X3,LSL #3 26 001c C41440A9 LDP X4,X5,[X6] 27 0020 BF0004EB CMP X5,X4 // if (toSort[j+1] < toSort[j]) 28 0024 6A000054 BGE L3 29 0028 C51000A9 STP X5,X4,[X6]// swap(toSort[j], toSort[j+1]); 30 002c F9FFFF17 B L2 // Край на вътрешния цикъл 31 0030 42040091 L3: ADD X2,X2,#1// else break; ++i) 32 0034 F4FFFF17 B L1 // Край на външния цикъл 33 0038 C0035FD6 L4: RET ARC GAS inssort.s page 1 1 # Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 # вмъкването масив от думи със знак с начален адрес в регистър r0 и брой 3 # елементи (поне 2) в регистър r1. 4 5 /* void insertionSort(vector& toSort) # Из книгата "Теоретични 6 { # алгоритми на C++" от 7 for (int i = 1; i < toSort.size(); ++i) # Кевин де Кайзер (2015 г.) 8 for (int j = i - 1; j >= 0; --j) 9 if (toSort[j+1] < toSort[j]) 10 swap(toSort[j], toSort[j+1]); 11 else # Тези 2 реда ги няма в 12 break; # горепосочената книга! 13 } */ 14 15 # Нека индексът на външния цикъл (i) е r2, а на вътрешния (j) е r3. 16 17 .global inssort 18 inssort: 19 0000 01DA MOVL_S r2,1 # for (unsigned i = 1; 20 0002 0D59 8080 L1: RCMPL r1,r2 # i < toSort.size(); 21 0006 E07C JEQ_S [blink] # Върни управлението 22 0008 4443 MOVL_S r3,r2 # for (unsigned j = i 23 000a 425B 4380 L2: SUBL.F r3,r3,1 # - 1; --j) 24 000e 8DF7 BLO_S L3 # j != -1; 25 0010 1658 C600 ADD3L r6,r0,r3 26 0014 0016 8406 LDDL r4,[r6] 27 0018 0F0D 0B01 BRGEL r5,r4,L3# if (toSort[j+1] < toSort[j]) 28 001c 081E 0701 STL r4,[r6,8] 29 0020 001E 4701 STL r5,[r6] # swap(toSort[j], toSort[j+1]); 30 0024 F3F1 B_S L2 # Край на вътрешния цикъл 31 0026 405A 4200 L3: ADDL r2,r2,1 # else break; ++i) 32 002a EDF1 B_S L1 # Край на външния цикъл PPC LISTING inssort.s page 1 1 # Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 # вмъкването масив от думи със знак с начален адрес в регистър r3 и брой 3 # елементи (поне 2) в регистър r4. 4 5 #void insertionSort(vector& toSort) // Из книгата "Теоретични 6 #{ // алгоритми на C++" от 7 # for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 # for (int j = i - 1; j >= 0; --j) 9 # if (toSort[j+1] < toSort[j]) 10 # swap(toSort[j], toSort[j+1]); 11 # else // Тези 2 реда ги няма в 12 # break; // горепосочената книга! 13 #} 14 15 # Нека индексът на външния цикъл (i) е r5, а на вътрешния (j) е r6. 16 17 .global inssort 18 inssort: 19 0000 38A00001 li r5,1 #for (int i = 1; 20 0004 7C252000 L1: cmpd r5,r4 # i < toSort.size(); 21 0008 4C800020 bgelr # Иначе край 22 000c 7CA62B78 mr r6,r5 # for (int j = i 23 0010 34C6FFFF L2: addic. r6,r6,-1# - 1; --j) 24 0014 41800028 blt L3 # j >= 0; 25 0018 78C91F24 sldi r9,r6,3 # Превърни индекса в адресно отместване 26 001c 7D234A14 add r9,r3,r9# Получи адреса на toSort[j] 27 0020 E8E90000 ld r7,0(r9)# toSort[j] 28 0024 E9090008 ld r8,8(r9)# toSort[j+1] 29 0028 7C283800 cmpd r8,r7 # if (toSort[j+1] < toSort[j]) 30 002c 40800010 bge L3 31 0030 F8E90008 std r7,8(r9)# swap(toSort[j], toSort[j+1]; 32 0034 F9090000 std r8,0(r9) 33 0038 4BFFFFD8 b L2 # Край на вътрешния цикъл 34 003c 38A50001 L3: addi r5,r5,1 # else break; ++i) 35 0040 4BFFFFC4 b L1 # Край на външния цикъл SPARC GAS inssort.s page 1 1 ! Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 ! вмъкването масив от думи със знак с начален адрес в регистър %o0 и брой 3 ! елементи (поне 2) в регистър %o1. 4 5 /* void insertionSort(vector& toSort) // Из книгата "Теоретични 6 { // алгоритми на C++" от 7 for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 for (int j = i - 1; j >= 0; --j) 9 if (toSort[j+1] < toSort[j]) 10 swap(toSort[j], toSort[j+1]); 11 else // Тези 2 реда ги няма в 12 break; // горепосочената книга! 13 } */ 14 15 ! Нека индексът на външния цикъл (i) е %o2, а на вътрешния (j) е %o3. 16 17 .global inssort 18 inssort: 19 0000 94102001 mov 1,%o2 !for (unsigned i = 1; 20 0004 80A28009 L1: cmp %o2,%o1 21 0008 1A680010 bcc %xcc,L4 ! i < toSort.size(); 22 000c 9610000A mov %o2,%o3 ! for (unsigned j = i 23 0010 96A2E001 L2: subcc %o3,1,%o3! - 1; --j) 24 0014 0A68000B bcs %xcc,L3 ! j != -1; 25 0018 992AF003 sllx %o3,3,%o4 ! Превърни индекса в адресно отместване 26 001c 9802000C add %o0,%o4,%o4! Получи адреса на toSort[j] 27 0020 DA5B0000 ldx [%o4],%o5 28 0024 C25B2008 ldx [%o4+8],%g1 29 0028 80A0400D cmp %g1,%o5 ! if (toSort[j+1] < toSort[j]) 30 002c 16680005 bge %xcc,L3 31 0030 01000000 nop 32 0034 DA732008 stx %o5,[%o4+8]! swap(toSort[j], toSort[j+1]; 33 0038 10BFFFF6 ba L2 ! Край на вътрешния цикъл; изпълнява се след „st“! 34 003c C2730000 stx %g1,[%o4] 35 0040 10BFFFF1 L3: ba L1 ! Край на външния цикъл; изпълнява се след „add“! 36 0044 9402A001 add %o2,1,%o2! else break; ++i) 37 0048 81C3E008 L4: retl 38 004c 01000000 nop MIPS LISTING inssort.s page 1 1 # Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 # вмъкването масив от думи със знак с начален адрес в регистър $4 и брой 3 # елементи (поне 2) в регистър $5. 4 5 #void insertionSort(vector& toSort) // Из книгата "Теоретични 6 #{ // алгоритми на C++" от 7 # for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 # for (int j = i - 1; j >= 0; --j) 9 # if (toSort[j+1] < toSort[j]) 10 # swap(toSort[j], toSort[j+1]); 11 # else // Тези 2 реда ги няма в 12 # break; // горепосочената книга! 13 #} 14 15 # Нека индексът на външния цикъл (i) е $6, а на вътрешния (j) е $7. 16 17 .ent inssort 18 .global inssort 19 inssort: 20 0000 24060001 LI $6,1 #for (int i = 1; 21 0004 00C5082A 10200011 00000000 L1: BGE $6,$5,L4# i < toSort.size(); 22 0010 00C03825 MOVE $7,$6 # for (int j = i 23 0014 64E7FFFF L2: DADDIU $7,$7,-1# - 1; --j) 24 0018 04E0000B 00000000 BLTZ $7,L3 # j >= 0; 25 0020 000750F8 DSLL $10,$7,3 # Превърни индекса в адресно отместване 26 0024 008A502D DADDU $10,$4,$10# Получи адреса на toSort[j] 27 0028 DD480000 LD $8,0($10) # toSort[j] 28 002c DD490008 LD $9,8($10) # toSort[j+1] 29 0030 0128082A 10200004 00000000 BGE $9,$8,L3 # if (toSort[j+1] < toSort[j]) 30 003c FD480008 SD $8,8($10) # swap(toSort[j], toSort[j+1]; 31 SD $9,0($10) 32 0040 1000FFF4 FD490000 B L2 # Край на вътрешния цикъл 33 L3: DADDIU $6,$6,1 # else break; ++i) 34 0048 1000FFEE 64C60001 B L1 # Край на външния цикъл 35 0050 03E00008 00000000 L4: JR $31 36 0058 00000000 00000000 .end inssort RISC-V LISTING inssort.s page 1 1 # Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 # вмъкването масив от думи със знак с начален адрес в регистър a0 и брой 3 # елементи (поне 2) в регистър a1. 4 5 #void insertionSort(vector& toSort) // Из книгата "Теоретични 6 #{ // алгоритми на C++" от 7 # for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 # for (int j = i - 1; j >= 0; --j) 9 # if (toSort[j+1] < toSort[j]) 10 # swap(toSort[j], toSort[j+1]); 11 # else // Тези 2 реда ги няма в 12 # break; // горепосочената книга! 13 #} 14 15 # Нека индексът на външния цикъл (i) е a2, а на вътрешния (j) е a3. 16 17 .global inssort 18 inssort: 19 0000 13061000 LI a2,1 #for (int i = 1; 20 0004 635CB602 L1: BGE a2,a1,L4# i < toSort.size(); 21 0008 93060600 MV a3,a2 # for (int j = i 22 000c 9386F6FF L2: ADDI a3,a3,-1# - 1; --j) 23 0010 63C20602 BLTZ a3,L3 # j >= 0; 24 0014 13983600 SLLI a6,a3,3 # Превърни индекса в адресно отместване 25 0018 33080501 ADD a6,a0,a6# Получи адреса на toSort[j] 26 001c 03370800 LD a4,0(a6)# toSort[j] 27 0020 83378800 LD a5,8(a6)# toSort[j+1] 28 0024 63D8E700 BGE a5,a4,L3# if (toSort[j+1] < toSort[j]) 29 0028 2334E800 SD a4,8(a6)# swap(toSort[j], toSort[j+1]); 30 002c 2330F800 SD a5,0(a6) 31 0030 6FF0DFFD J L2 # Край на вътрешния цикъл 32 0034 13061600 L3: ADDI a2,a2,1 # else break; ++i) 33 0038 6FF0DFFC J L1 # Край на външния цикъл 34 003c 67800000 L4: RET LOONGARCH64 GAS inssort.s page 1 1 # Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 # вмъкването масив от думи със знак с начален адрес в регистър r4 и брой 3 # елементи (поне 2) в регистър r5. 4 5 #void insertionSort(vector& toSort) // Из книгата "Теоретични 6 #{ // алгоритми на C++" от 7 # for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 # for (int j = i - 1; j >= 0; --j) 9 # if (toSort[j+1] < toSort[j]) 10 # swap(toSort[j], toSort[j+1]); 11 # else // Тези 2 реда ги няма в 12 # break; // горепосочената книга! 13 #} 14 15 # Нека индексът на външния цикъл (i) е r6, а на вътрешния (j) е r7. 16 17 .global inssort 18 inssort: 19 0000 06048003 ORI $r6,$r0,1#for (int i = 1; 20 0004 C5340064 L1: BGE $r6,$r5,L4 # i < toSort.size(); 21 0008 C7001500 OR $r7,$r6,$r0# for (int j = i 22 000c E7FCFF02 L2: ADDI.D $r7,$r7,-1 # - 1; --j) 23 0010 E0200060 BLTZ $r7,L3 # j >= 0; 24 0014 EA102D00 ALSL.D $r10,$r7,$r4,3# Получи адреса на toSort[j] 25 0018 4801C028 LD.D $r8,$r10,0 # toSort[j] 26 001c 4921C028 LD.D $r9,$r10,8 # toSort[j+1] 27 0020 28110064 BGE $r9,$r8,L3 # if (toSort[j+1] < toSort[j]) 28 0024 4821C029 ST.D $r8,$r10,8 # swap(toSort[j], toSort[j+1]; 29 0028 4901C029 ST.D $r9,$r10,0 30 002c FFE3FF53 B L2 # Край на вътрешния цикъл 31 0030 C604C002 L3: ADDI.D $r6,$r6,1 # else break; ++i) 32 0034 FFD3FF53 B L1 # Край на външния цикъл 33 0038 2000004C L4: JIRL $r0,$r1,0 # Да се напише подпрограма, която да сортира във възходящ ред по метода на # вмъкването масив от думи със знак с начален адрес в регистър $16 и брой # елементи (поне 2) в регистър $17. #void insertionSort(vector& toSort) // Из книгата "Теоретични #{ // алгоритми на C++" от # for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) # for (int j = i - 1; j >= 0; --j) # if (toSort[j+1] < toSort[j]) # swap(toSort[j], toSort[j+1]); # else // Тези 2 реда ги няма в # break; // горепосочената книга! #} inssort.o: file format ecoff-littlealpha # Нека индексът на външния цикъл (i) е $0, а на вътрешния (j) е $1. Disassembly of section .text: .ent inssort .globl inssort 0000000000000000 : inssort: 0: 01 00 1f 20 lda v0,1(zero) lda $0,1($31)#for (int i = 1; 4: a2 09 11 40 cmplt v0,a1,t1 L1: cmplt $0,$17,$2# i < toSort.size(); 8: 0d 00 40 e4 beq t1,40 beq $2,L4 c: 01 04 1f 44 or v0,zero,t0 bis $0,$31,$1# for (int j = i 10: 21 35 20 40 subq t0,0x1,t0 L2: subq $1,1,$1 # - 1; --j) 14: 08 00 20 e8 blt t0,38 blt $1,L3 # j >= 0; 18: 42 06 30 40 s8addq t0,a0,t1 s8addq $1,$16,$2# Получи адреса на toSort[j] 1c: 00 00 62 a4 ldq t2,0(t1) ldq $3,0($2) # toSort[j] 20: 08 00 82 a4 ldq t3,8(t1) ldq $4,8($2) # toSort[j+1] 24: a5 09 83 40 cmplt t3,t2,t4 cmplt $4,$3,$5 # if (toSort[j+1] < toSort[j]) 28: 03 00 a0 e4 beq t4,38 beq $5,L3 2c: 08 00 62 b4 stq t2,8(t1) stq $3,8($2) # swap(toSort[j], toSort[j+1]; 30: 00 00 82 b4 stq t3,0(t1) stq $4,0($2) 34: f6 ff ff c3 br 10 br $31,L2 # Край на вътрешния цикъл 38: 00 34 00 40 addq v0,0x1,v0 L3: addq $0,1,$0 # else break; ++i) 3c: f1 ff ff c3 br 4 br $31,L1 # Край на външния цикъл 40: 01 80 fa 6b ret zero,(ra),0x1 L4: ret 44: 1f 04 ff 47 nop .end inssort 48: 00 00 fe 2f unop 4c: 1f 04 ff 47 nop GAS for MMIX inssort.s page 1 1 % Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 % вмъкването масив от думи със знак с начален адрес в регистър $0 и брой 3 % елементи (поне 2) в регистър $1. 4 5 %void insertionSort(vector& toSort) // Из книгата "Теоретични 6 %{ // алгоритми на C++" от 7 % for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 % for (int j = i - 1; j >= 0; --j) 9 % if (toSort[j+1] < toSort[j]) 10 % swap(toSort[j], toSort[j+1]); 11 % else // Тези 2 реда ги няма в 12 % break; // горепосочената книга! 13 %} 14 15 % Нека индексът на външния цикъл (i) е $2, а на вътрешния (j) е $3. 16 17 .global inssort 18 inssort: 19 0000 E3020001 SETL $2,1 %for (int i = 1; 20 0004 30040201 L1: CMP $4,$2,$1% i < toSort.size(); 21 0008 4804000E BNN $4,L4 22 000c C1030200 OR $3,$2,0 % for (int j = i 23 0010 27030301 L2: SUBU $3,$3,1 % - 1; --j) 24 0014 40030009 BN $3,L3 % j >= 0; 25 0018 2C040300 8ADDU $4,$3,$0% Получи адреса на toSort[j] 26 001c 8D050400 LDO $5,$4,0 % toSort[j] 27 0020 8D060408 LDO $6,$4,8 % toSort[j+1] 28 0024 30070605 CMP $7,$6,$5% if (toSort[j+1] < toSort[j]) 29 0028 48070004 BNN $7,L3 30 002c AD050408 STO $5,$4,8 % swap(toSort[j], toSort[j+1]; 31 0030 AD060400 STO $6,$4,0 32 0034 F1FFFFF7 JMP L2 % Край на вътрешния цикъл 33 0038 23020201 L3: ADDU $2,$2,1 % else break; ++i) 34 003c F1FFFFF2 JMP L1 % Край на външния цикъл 35 0040 F8000000 L4: POP 0,0 HPPA64 LISTING inssort.s page 1 1 ; Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 ; вмъкването масив от думи със знак с начален адрес в регистър %R26 и брой 3 ; елементи (поне 2) в регистър %R25. 4 5 ;void insertionSort(vector& toSort) // Из книгата "Теоретични 6 ;{ // алгоритми на C++" от 7 ; for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 ; for (int j = i - 1; j >= 0; --j) 9 ; if (toSort[j+1] < toSort[j]) 10 ; swap(toSort[j], toSort[j+1]); 11 ; else // Тези 2 реда ги няма в 12 ; break; // горепосочената книга! 13 ;} 14 15 ; Нека индексът на външния цикъл (i) е %R24, а на вътрешния (j) е %R23. 16 17 .global inssort 18 inssort: 19 0000 34180002 LDI 1,%R24 ;for (int i = 1; 20 0004 BF384058 L1: CMPB,*>= %R24,%R25,L4; i < toSort.size(); 21 0008 08180257 COPY %R24,%R23 ; for (int j = i // Изпълнява се преди „CMPB“! 22 000c B6F707FF L2: ADDI -1,%R23,%R23; - 1; --j) 23 0010 EEE0E030 CMPIB,*> 0,%R23,L3 ; j >= 0; 24 0014 0B570AD4 SHLADD,L %R23,3,%R26,%R20;Адрес на toSort[j], изпълн. се преди „CMPIB“! 25 0018 0E8010D5 LDD 0(%R20),%R21; toSort[j] 26 001c 0E9010D6 LDD 8(%R20),%R22; toSort[j+1] 27 0020 BEB64012 CMPB,*>=,N %R22,%R21,L3;При if (toSort[j+1] < toSort[j]) 28 0024 0E9512D0 STD %R21,8(%R20);<-скок се анулира swap(toSort[j], toSort[j+1]); 29 0028 E81F1FBD B L2 ; Край на вътрешния цикъл 30 002c 0E9612C0 STD %R22,0(%R20); Изпълнява се преди „B“! 31 0030 AF021F9D L3: ADDIB,TR 1,%R24,L1 ; else break; ++i) 32 0034 08000240 NOP ;\_ Край на външния цикъл 33 0038 E840D002 L4: BVE,N (%R2) TILE-Gx GAS inssort.s page 1 1 # Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 # вмъкването масив от думи със знак с начален адрес в регистър r0 и брой 3 # елементи (поне 2) в регистър r1. 4 5 #void insertionSort(vector& toSort) // Из книгата "Теоретични 6 #{ // алгоритми на C++" от 7 # for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 # for (int j = i - 1; j >= 0; --j) 9 # if (toSort[j+1] < toSort[j]) 10 # swap(toSort[j], toSort[j+1]); 11 # else // Тези 2 реда ги няма в 12 # break; // горепосочената книга! 13 #} 14 15 # Нека индексът на външния цикъл (i) е r2, а на вътрешния (j) е r3. 16 17 .global inssort 18 inssort: 19 0000 00304851 E10F0818 MOVEI r2,1 #for (int i = 1; 20 0008 00304851 42081428 L1: CMPLTS r4,r2,r1# i < toSort.size(); 21 { BEQZ r4,L4 22 0010 83F007D1 85004014 MOVE r3,r2 } # for (int j = i 23 0018 003048D1 61F80F18 L2: ADDI r3,r3,-1# - 1; --j) 24 { BLTZ r3,L3 # j >= 0; 25 0020 C4002051 64004017 SHL3ADD r4,r3,r0}#Получи адреса на toSort[j] 26 0028 003048D1 8240A018 LD_ADD r5,r4,8 # toSort[j] 27 0030 00304C34 0040369E LD r6,r4 # toSort[j+1] 28 0038 003048D1 C3281428 CMPLTS r7,r6,r5# if (toSort[j+1] < toSort[j]) 29 0040 00304851 E2004014 BEQZ r7,L3 30 0048 00304851 9C280619 ST_ADD r4,r5,-8# swap(toSort[j], toSort[j+1]; 31 0050 00304C34 004036DE ST r4,r6 32 0058 00304851 FCFFFF27 J L2 # Край на вътрешния цикъл 33 L3: { ADDI r2,r2,1 # else break; ++i) 34 0060 821010C0 FAFFFF27 J L1 } # Край на външния цикъл 35 0068 00304851 E0766A28 L4: JR lr IA-64 GAS inssort.s page 1 1 // Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 // вмъкването масив от думи със знак с начален адрес в регистър in0 и брой 3 // елементи (поне 2) в регистър in1. 4 5 //void insertionSort(vector& toSort) // Из книгата "Теоретични 6 //{ // алгоритми на C++" от 7 // for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 // for (int j = i - 1; j >= 0; --j) 9 // if (toSort[j+1] < toSort[j]) 10 // swap(toSort[j], toSort[j+1]); 11 // else // Тези 2 реда ги няма в 12 // break; // горепосочената книга! 13 //} 14 15 // Нека индексът на външния цикъл (i) е loc0, а на вътрешния (j) е loc1. 16 17 .global inssort 18 inssort: 19 ALLOC loc5=ar.pfs,2,6,0,0 20 MOV loc0=1//for (int i = 1; 21 L1: CMP.LT p6,p7=loc0,in1// i < toSort.size(); 22 0000 01382110 8005200A 00004800 00000400 (p7) BR.RET.SPTK rp 23 MOV loc1=loc0 //for (int j = i 24 0010 10308842 07300000 00028083 00008400 L2: SUB loc1=loc1,r0,1// - 1; --j) 25 CMP.NE p6,p7=-1,loc1 // j >= 0; 26 0020 01180144 00210000 00020000 00000400 (p6) SHLADD loc2=loc1,3,in0//Получи адреса на toSort[j] 27 0030 0B188D00 042070F8 8F0C7600 00000400 (p6) LD8 loc3=[loc2],8 // toSort[j] 28 (p6) LD8 loc4=[loc2] // toSort[j+1] 29 0040 CB208D40 12A05142 90302800 00000400 (p6) CMP.LT p6,p7=loc4,loc3// if (toSort[j+1] < toSort[j]) 30 (p6) ST8 [loc2]=loc3,-8// swap(toSort[j], toSort[j+1]; 31 0050 CB300148 18906130 950E6000 00000400 (p6) ST8 [loc2]=loc4 32 (p6) BR L2 // Край на вътрешния цикъл 33 0060 CAC09748 99970130 91302300 00000400 ADD loc0=loc0,r0,1// else break; ++i) 34 0070 10000000 01000000 00020003 C0FFFF48 BR L1 // Край на външния цикъл 34 11108900 01200000 00020000 90FFFF48 E2K GAS inssort.s page 1 1 ! Да се напише подпрограма, която да сортира във възходящ ред по метода на 2 ! вмъкването масив от думи със знак с начален адрес в регистър r0 и брой 3 ! елементи (поне 2) в регистър r1. 4 5 !void insertionSort(vector& toSort) // Из книгата "Теоретични 6 !{ // алгоритми на C++" от 7 ! for (int i = 1; i < toSort.size(); ++i) // Кевин де Кайзер (2015 г.) 8 ! for (int j = i - 1; j >= 0; --j) 9 ! if (toSort[j+1] < toSort[j]) 10 ! swap(toSort[j], toSort[j+1]); 11 ! else // Тези 2 реда ги няма в 12 ! break; // горепосочената книга! 13 !} 14 15 ! Нека индексът на външния цикъл (i) е r2, а на вътрешния (j) е r3. 16 17 .global inssort 18 inssort: 19 { setwd wsz=7,nfx=1 ! wsz = брой използвани регистри, nfx = неясно! 20 return %ctpr3 ! Подготви връщането към извикващата функция 21 0000 23C00004 82C1C005 000000F0 00000000 00000000 F0000000 ord 0,1,%r2}!for (int i = 1; 22 L1: { cmpldb %r2,%r1,%pred0 ! i < toSort.size(); 23 0018 12400004 C0818221 04000040 00000000 disp %ctpr1,L2 } ! Подготви прехода към началото на вътрешния 24 { ct %ctpr3 ? ~%pred0! цикъл 25 0028 12100004 600C00C0 83C08205 00000000 ord %r2,0,%r3 } !for (int j = i 26 L2: { cmpldb 0,%r3,%pred0 ! - 1; --j) 27 0038 1200000C C083C021 83C18313 00000000 subd %r3,1,%r3 } ! j >= 0; 28 0048 11002108 84C38319 0000800A 00006008 shl_addd %r3,3,%r0,%r4 ? %pred0!Получи адреса на toSort[j] 29 { ldd [%r4+0],%r5 ? %pred0 !toSort[j] 30 0058 12000114 85C08467 86C88467 00006014 ldd [%r4+8],%r6 ? %pred0 } !toSort[j+1] 31 0068 11010104 C0858621 00000000 00006004 cmpldb %r6,%r5,%pred0 ? %pred0!if (toSort[j+1] < toSort[j]) 32 { std %r5,[%r4+8] ? %pred0! swap(toSort[j], toSort[j+1]; 33 std %r6,[%r4+0] ? %pred0 34 0078 23100190 400400C0 85C88427 86C08427 00000000 60506010 ct %ctpr1 ? %pred0}! Край на вътрешния цикъл 35 { addd %r2,1,%r2 ! else break; ++i) 36 0090 12400004 82C18211 F1FFFF4F 00000000 disp %ctpr1,L1 } !Подготви прехода към началото на външния цикъл 37 00a0 01100000 200400C0 ct %ctpr1 !Край на външния цикъл S/390x LISTING heapSort.s page 1 1 # Подреди във възходящ ред масив от рег.3 (> 2) думи със знак, указани от рег.2 2 # Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 # average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 #/* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 #void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 #{ // най-големия възел в корена му 8 # int i, tmp; 9 # 10 # n--; // Премини към база 0 11 # for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 # i = 2 * k; // Ляв потомък 13 # if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 # i++; // левия и избери по-големия 15 # if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 # break; // на най-големия потомък, клонът е OK 17 # a[k] = a[i]; // Иначе потомъкът застава на мястото 18 # } // на родителя 19 # a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 #} // потомък, освен ако е по-голям от всички потомци 21 # 22 #void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 #{ // Сортиращо дърво, heap, tas: пирамида 24 # int i, tmp; 25 # 26 # for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 # downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 # for (i = n - 1; i > 0; i--) { 29 # tmp = a[i]; // Размени местата на максимума 30 # a[i] = a[0]; // и последния елемент на масива 31 # a[0] = tmp; 32 # downHeap(a, 0, i); // Препострой сортиращото дърво за 33 # } // неотсортираната част от масива 34 #} 35 #*/ 36 37 .global heapSort #void heapSort(int *a, int n) // 2, 3 38 heapSort: #{ int i, tmp; // 5 (3), 5 39 0000 EB68F010 0024 STMG 6,8,16(15) #Съхрани използваните регистри (LNUX-1007-02) 40 0006 B9040053 LGR 5,3 # for (i = n 41 000a EB550001 000C SRLG 5,5,1 # / 2; i >= 0; i--) 42 0010 A73BFFFF AGHI 3,-1 #n-- 43 0014 B9040045 L1: LGR 4,5 #i 44 0018 A7850024 BRAS 8,DownHeap # downHeap(a, i, n); // 2,4,3 45 001c A75BFFFF AGHI 5,-1 # // i--) 46 0020 A7B4FFFA JNL L1 # // i >= 0; 47 0024 E3602000 0004 L2: LG 6,0(2) #a[0] for (i = n - 1; i > 0; i--) { // 3 = i 48 002a B9040013 LGR 1,3 #i 49 002e EB110003 000D SLLG 1,1,3 #8*i 50 0034 E3521000 0004 LG 5,0(2,1) # tmp = a[i]; 51 003a E3621000 0024 STG 6,0(2,1) # a[i] = a[0]; 52 0040 E3502000 0024 STG 5,0(2) # a[0] = tmp; 53 0046 B9820044 XGR 4,4 #k = 0 54 004a A73BFFFF AGHI 3,-1 #i-- (n--) 55 004e A7850009 BRAS 8,DownHeap # downHeap(a, 0, i); // 2,4,3 56 0052 EC36FFE9 007D CLGIJNE 3,0,L2 # } // i > 0 57 0058 EB68F010 0004 LMG 6,8,16(15) #Възстанови съхранените регистри 58 005e 07FE BR 14 #} 59 0060 B9040014 DownHeap: LGR 1,4 #k 60 0064 EB110003 000D SLLG 1,1,3 #8*k void downHeap(int *a, int k, int n)// 2,4,3 61 006a E3721000 0004 LG 7,0(2,1)#tmp=a[k]{ 62 0070 B9040013 L3: LGR 1,3 #n int i,tmp;/* 6,7 */n--;//вече намалено 63 0074 EB110001 000C SRLG 1,1,1 #n / 2 for (tmp = a[k]; k <= n / 2; k = i) { 64 007a EC410031 2065 CLGRJH 4,1,L5 #k <= n / 2? 65 0080 B9040064 LGR 6,4 #k 66 0084 EB660001 000D SLLG 6,6,1 # i = 2 * k; 67 008a B9040016 LGR 1,6 #i 68 008e EB110003 000D SLLG 1,1,3 #8*i 69 0094 EC63000D A065 CLGRJNL 6,3,L4 # if (i < n && 70 009a E3021000 0004 LG 0,0(2,1) #a[i] 71 00a0 E3021008 0020 CG 0,8(2,1) # a[i] < a[i+1]) 72 00a6 A7B40004 JNL L4 73 00aa A76B0001 AGHI 6,1 # i++; 74 00ae B9040016 L4: LGR 1,6 #i 75 00b2 EB110003 000D SLLG 1,1,3 #8*i 76 00b8 E3021000 0004 LG 0,0(2,1) #a[i] 77 00be EC70000F A064 CGRJNL 7,0,L5 # if (tmp >= a[i]) break; 78 00c4 B9040014 LGR 1,4 #k 79 00c8 EB110003 000D SLLG 1,1,3 #8*k 80 00ce E3021000 0024 STG 0,0(2,1) # a[k] = a[i]; 81 00d4 B9040046 LGR 4,6 # } // k = i 82 00d8 A7F4FFCC J L3 83 00dc B9040014 L5: LGR 1,4 #k 84 00e0 EB110003 000D SLLG 1,1,3 #8*k 85 00e6 E3721000 0024 STG 7,0(2,1) # a[k] = tmp; 86 00ec 07F80707 BR 8 #} AMD64 GAS heapSort.s page 1 1 # Подреди във възходящ ред масив от RSI (RSI > 2) думи със знак, указан от RDI 2 # Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 # average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 #/* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 #void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 #{ // най-големия възел в корена му 8 # int i, tmp; 9 # 10 # n--; // Премини към база 0 11 # for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 # i = 2 * k; // Ляв потомък 13 # if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 # i++; // левия и избери по-големия 15 # if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 # break; // на най-големия потомък, клонът е OK 17 # a[k] = a[i]; // Иначе потомъкът застава на мястото 18 # } // на родителя 19 # a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 #} // потомък, освен ако е по-голям от всички потомци 21 # 22 #void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 #{ // Сортиращо дърво, heap, tas: пирамида 24 # int i, tmp; 25 # 26 # for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 # downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 # for (i = n - 1; i > 0; i--) { 29 # tmp = a[i]; // Размени местата на максимума 30 # a[i] = a[0]; // и последния елемент на масива 31 # a[0] = tmp; 32 # downHeap(a, 0, i); // Препострой сортиращото дърво за 33 # } // неотсортираната част от масива 34 #} 35 #*/ 36 37 .intel_syntax noprefix 38 .global heapSort 39 heapSort: # void heapSort(int *a, int n) 40 0000 4889F2 MOV RDX,RSI # i = n { int i, tmp; // RDX (RSI), RCX 41 0003 48D1EA SHR RDX,1 # i = n / 2 for (i = n / 2; i >= 0; i--) 42 0006 48FFCE DEC RSI # n-- 43 0009 4989D1 L1: MOV R9,RDX # i 44 000c E8210000 00 CALL DOWNHEAP#арг.:RDI,R9,RSI downHeap(a, i, n); 45 0011 48FFCA DEC RDX # i-- 46 0014 79F3 JNS L1 # ако i >= 0, продължи 47 0016 4D31C9 L2: XOR R9,R9 # k = 0 for (i = n - 1; i > 0; i--) { 48 0019 488B0CF7 MOV RCX,[RDI+8*RSI]# tmp = a[i]; 49 001d 48870F XCHG RCX,[RDI]#_________ _____ a[i] = a[0]; 50 0020 48890CF7 MOV [RDI+8*RSI],RCX#___X_____ a[0] = tmp; 51 0024 48FFCE DEC RSI # i-- (n--) 52 0027 E8060000 00 CALL DOWNHEAP#арг.:RDI,RDX,RSI downHeap(a, 0, i); 53 002c 4885F6 TEST RSI,RSI 54 002f 75E5 JNZ L2 # } 55 0031 C3 RET # }void downHeap(int*a,int k,int n)//RDI,R9,RSI 56 0032 4A8B0CCF DOWNHEAP: MOV RCX,[RDI+8*R9]# { int i,tmp;/*R10,RCX*/n--;вече умалено 57 0036 4989F0 L3: MOV R8,RSI # n for (tmp = a[k]; k <= n / 2; k = i) { 58 0039 49D1E8 SHR R8,1 # n / 2 59 003c 4D39C1 CMP R9,R8 # k <= n / 2 ? 60 003f 772D JA L5 # ако не, край на цикъла 61 0041 4E8D144D 00000000 LEA R10,[2*R9]# i = 2 * k; 62 0049 4939F2 CMP R10,RSI # i < n ? if (i < n 63 004c 730E JAE L4 # ако не, прескочи && 64 004e 4E8B04D7 MOV R8,[RDI+8*R10]# a[i] < a[i+1]) 65 0052 4E3B44D7 08 CMP R8,[RDI+8*R10+8] 66 0057 7D03 JGE L4 67 0059 49FFC2 INC R10 # i++; 68 005c 4E8B04D7 L4: MOV R8,[RDI+8*R10] 69 0060 4C39C1 CMP RCX,R8 # if (tmp >= a[i]) 70 0063 7D09 JGE L5 # break; 71 0065 4E8904CF MOV [RDI+8*R9],R8# a[k] = a[i]; 72 0069 4D89D1 MOV R9,R10 # k = i } 73 006c EBC8 JMP L3 74 006e 4A890CCF L5: MOV [RDI+8*R9],RCX# a[k] = tmp; 75 0072 C3 RET # } AARCH64 GAS heapSort.s page 1 1 // Подреди във възходящ ред масив от X1 (X1 > 2) думи със знак, указани от X0 2 // Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 // average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 /* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 { // най-големия възел в корена му 8 int i, tmp; 9 10 n--; // Премини към база 0 11 for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 i = 2 * k; // Ляв потомък 13 if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 i++; // левия и избери по-големия 15 if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 break; // на най-големия потомък, клонът е OK 17 a[k] = a[i]; // Иначе потомъкът застава на мястото 18 } // на родителя 19 a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 } // потомък, освен ако е по-голям от всички потомци 21 22 void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 { // Сортиращо дърво, heap, tas: пирамида 24 int i, tmp; 25 26 for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 for (i = n - 1; i > 0; i--) { 29 tmp = a[i]; // Размени местата на максимума 30 a[i] = a[0]; // и последния елемент на масива 31 a[0] = tmp; 32 downHeap(a, 0, i); // Препострой сортиращото дърво за 33 } // неотсортираната част от масива 34 } 35 */ 36 37 .global heapSort //void heapSort(int *a, int n) //X0, X1 38 heapSort: // { | int i, tmp; // X3 (X1), X3 39 0000 E8031EAA MOV X8,LR //Съхрани LR, защото BL ще го промени! 40 0004 E30741AA MOV X3,X1,LSR #1 // | for (i = n / 2; i >= 0; i--) 41 0008 210400D1 SUB X1,X1,#1 //n-- | 42 000c E20303AA L1: MOV X2,X3 // i | 43 0010 0C000094 BL DOWNHEAP // | downHeap(a, i, n); //X0,X2,X1 44 0014 630400F1 SUBS X3,X3,#1 // | // i--) 45 0018 A2FFFF54 BHS L1 // | // i >= 0; 46 001c 040040F9 L2: LDR X4,[X0] // | for (i = n - 1; i > 0; i--) {//X1 = i 47 0020 037861F8 LDR X3,[X0,X1,LSL #3]// | tmp = a[i]; 48 0024 047821F8 STR X4,[X0,X1,LSL #3]// | a[i] = a[0]; 49 0028 030000F9 STR X3,[X0] // | a[0] = tmp; 50 002c E2031FAA MOV X2,XZR // k = 0 | 51 0030 210400D1 SUB X1,X1,#1// i-- (n--) | downHeap(a, 0, i); //X0,X2,X1 52 0034 03000094 BL DOWNHEAP// | } 53 0038 21FFFFB5 CBNZ X1,L2 // ____} // i > 0; 54 003c 00011FD6 BR X8 //___/ void downHeap(int *a, int k, int n)//X0,X2,X1 55 0040 057862F8 DOWNHEAP: LDR X5,[X0,X2,LSL #3]// | int i,tmp;/*X4,5*/n--;//вече намалено 56 0044 5F0441EB L3: CMP X2,X1,LSR #1//k <= n/2 ?| for (tmp = a[k]; k <= n / 2; k = i) { 57 0048 C8010054 BHI L5 // ако не, край на цикъла 58 004c E40702AA MOV X4,X2,LSL #1// | i = 2 * k; 59 0050 9F0001EB CMP X4,X1 // | if (i < n 60 0054 A2000054 BHS L4 // | 61 0058 060C048B ADD X6,X0,X4,LSL #3// | && 62 005c C61C40A9 LDP X6,X7,[X6]// | 63 0060 DF0007EB CMP X6,X7 // | a[i] < a[i+1]) 64 0064 84A4849A CINC X4,X4,LT// | i++; 65 0068 067864F8 L4: LDR X6,[X0,X4,LSL #3]// | 66 006c BF0006EB CMP X5,X6 // | if (tmp >= a[i]) 67 0070 8A000054 BGE L5 // | break; 68 0074 067822F8 STR X6,[X0,X2,LSL #3]// | a[k] = a[i]; 69 0078 E20304AA MOV X2,X4 // k = i | } 70 007c F2FFFF17 B L3 71 0080 057822F8 L5: STR X5,[X0,X2,LSL #3]// | a[k] = tmp; 72 0084 C0035FD6 RET // } ARC GAS heapSort.s page 1 1 # Подреди във възходящ ред масив от r1 (r1 > 2) думи със знак, указани от r0 2 # Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 # average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 /* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 void downHeap(int *a, int k, int n) # Прегледай поддървото и премести 7 { # най-големия възел в корена му 8 int i, tmp; 9 10 n--; # Премини към база 0 11 for (tmp = a[k]; k <= n / 2; k = i) { # В корена запомни родителя 12 i = 2 * k; # Ляв потомък 13 if (i < n && a[i] < a[i+1]) # Ако има десен, сравни го с 14 i++; # левия и избери по-големия 15 if (tmp >= a[i]) # Ако родителят е по-голям или равен 16 break; # на най-големия потомък, клонът е OK 17 a[k] = a[i]; # Иначе потомъкът застава на мястото 18 } # на родителя 19 a[k] = tmp; # Накрая родителят си разменя мястото с най-големия 20 } # потомък, освен ако е по-голям от всички потомци 21 22 void heapSort(int *a, int n) # Пирамидално сортиране (tri par tas) 23 { # Сортиращо дърво, heap, tas: пирамида 24 int i, tmp; 25 26 for (i = n / 2; i >= 0; i--) # Създай сортиращо дърво (максималният 27 downHeap(a, i, n); # елемент на масива ще бъде в корена) 28 for (i = n - 1; i > 0; i--) { 29 tmp = a[i]; # Размени местата на максимума 30 a[i] = a[0]; # и последния елемент на масива 31 a[0] = tmp; 32 downHeap(a, 0, i); # Препострой сортиращото дърво за 33 } # неотсортираната част от масива 34 } 35 */ 36 37 .global heapSort #void heapSort(int *a, int n) //r0, r1 38 heapSort: # { | int i, tmp; // r3 (r1), r3 39 0000 EF41 MOVL_S r9,blink #Съхрани blink, защото BL_S ще го промени! 40 0002 6159 4300 LSRL r3,r1,1 # | for (i = n / 2; i >= 0; i--) 41 0006 4259 4100 SUBL r1,r1,1 #n-- | 42 000a 6442 L1: MOVL_S r2,r3 # i | 43 000c 0BF8 BL_S DOWNHEAP # | downHeap(a, i, n); //r0,r2,r1 44 000e 425B 4380 SUBL.F r3,r3,1 # | // i--) 45 0012 7DF7 BHS_S L1 # | // i >= 0; 46 0014 0010 4408 L2: LDL r4,[r0] # a[0] | for (i = n - 1; i > 0; i--) {//r1 = i 47 0018 1658 4700 ADD3L r7,r0,r1# a + 8i | 48 001c 0017 4308 LDL r3,[r7] # | tmp = a[i]; 49 0020 001F 0701 STL r4,[r7] # | a[i] = a[0]; 50 0024 0018 C700 STL r3,[r0] # | a[0] = tmp; 51 0028 00DA MOVL_S r2,0 # k = 0 | 52 002a 4259 4100 SUBL r1,r1,1 # i-- (n--) | downHeap(a, 0, i); //r0,r2,r1 53 002e 03F8 BL_S DOWNHEAP# __________| } // i > 0; 54 0030 E509 1980 BRNEL r1,0,L2 #____/ }void downHeap(int *a, int k, int n)//r0,r2,r1 55 0034 2020 4002 J [r9] # { | int i,tmp;/*r4,5*/n--;//вече намалено 56 0038 F120 8580 DOWNHEAP: LDL.AS r5,[r0,r2]# | for (tmp = a[k]; k <= n / 2; k = i) { 57 003c 1658 8800 L3: ADD3L r8,r0,r2# a + 8k | 58 0040 6159 4700 LSRL r7,r1,1 # n / 2 | 59 0044 2D0F 8C00 BRLOL r7,r2,L5# k <= n / 2 ? ако не, край на цикъла 60 0048 605A 4400 ASLL r4,r2,1 # | i = 2 * k; 61 004c 150C 4D00 BRHSL r4,r1,L4# | if (i < n 62 0050 1658 0601 ADD3L r6,r0,r4# LDDL.AS не мащабира индекса! 63 0054 0016 8606 LDDL r6,[r6] # | && 64 0058 0D5F 8081 RCMPL r7,r6 # | a[i] < a[i+1]) 65 005c C05C 6B00 ADDL.LT r4,r4,1 # | i++; 66 0060 F120 0681 L4: LDL.AS r6,[r0,r4]#a[i] | 67 0064 0D0D 8B01 BRGEL r5,r6,L5# | if (tmp >= a[i]) break; 68 0068 0018 8711 STL r6,[r8] # | a[k] = a[i]; 69 006c 8442 MOVL_S r2,r4 # k = i | } 70 006e E8F1 B_S L3 71 0070 0018 4711 L5: STL r5,[r8] # | a[k] = tmp; 72 0074 E07E J_S [blink] # } PPC LISTING heapSort.s page 1 1 # Подреди във възходящ ред масив от r4 (r4 > 2) думи със знак, указани от r3 2 # Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 # average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 #/* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 #void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 #{ // най-големия възел в корена му 8 # int i, tmp; 9 # 10 # n--; // Премини към база 0 11 # for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 # i = 2 * k; // Ляв потомък 13 # if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 # i++; // левия и избери по-големия 15 # if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 # break; // на най-големия потомък, клонът е OK 17 # a[k] = a[i]; // Иначе потомъкът застава на мястото 18 # } // на родителя 19 # a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 #} // потомък, освен ако е по-голям от всички потомци 21 # 22 #void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 #{ // Сортиращо дърво, heap, tas: пирамида 24 # int i, tmp; 25 # 26 # for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 # downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 # for (i = n - 1; i > 0; i--) { 29 # tmp = a[i]; // Размени местата на максимума 30 # a[i] = a[0]; // и последния елемент на масива 31 # a[0] = tmp; 32 # downHeap(a, 0, i); // Препострой сортиращото дърво за 33 # } // неотсортираната част от масива 34 #} 35 #*/ 36 37 .global heapSort #void heapSort(int *a, int n) // r3, r4 38 heapSort: #{ int i, tmp; // r6 (r4), r6 39 0000 7C0802A6 mflr r0 #Съхрани lr, защото bl ще го промени! 40 0004 7886F842 srdi r6,r4,1 # for (i = n / 2; i >= 0; i--) 41 0008 3884FFFF addi r4,r4,-1 #n-- 42 000c 7CC53378 L1: mr r5,r6 #i 43 0010 48000039 bl DownHeap # downHeap(a, i, n); // r3,r5,r4 44 0014 34C6FFFF addic. r6,r6,-1 # // i--) 45 0018 4080FFF4 bge+ L1 # // i >= 0; 46 001c E8E30000 L2: ld r7,0(r3) #a[0] for (i = n - 1; i > 0; i--) { // r4 = i 47 0020 788B1F24 sldi r11,r4,3 #8*i 48 0024 7CC3582A ldx r6,r3,r11 # tmp = a[i]; 49 0028 7CE3592A stdx r7,r3,r11 # a[i] = a[0]; 50 002c F8C30000 std r6,0(r3) # a[0] = tmp; 51 0030 38A00000 li r5,0 #k = 0 52 0034 3484FFFF addic. r4,r4,-1 #i-- (n--) 53 0038 48000011 bl DownHeap # downHeap(a, 0, i); // r3,r5,r4 54 003c 4082FFE0 bne+ L2 # } // i > 0 55 0040 7C0803A6 mtlr r0 #} 56 0044 4E800020 blr 57 0048 78AB1F24 DownHeap: sldi r11,r5,3 #8*k void downHeap(int *a, int k, int n)// r3,r5,r4 58 004c 7D03582A ldx r8,r3,r11#tmp=a[k]{ int i,tmp;/* r7,8 */n--;//вече намалено 59 0050 788BF842 L3: srdi r11,r4,1 #n / 2 for (tmp = a[k]; k <= n / 2; k = i) { 60 0054 7CA55840 cmpld cr1,r5,r11#k <= n / 2 (cr0 зает)? 61 0058 4185004C bgt- cr1,L5 #ако не, край на цикъла 62 005c 78A70FA4 sldi r7,r5,1 # i = 2 * k; 63 0060 78EB1F24 sldi r11,r7,3 #8*i 64 0064 7D635A14 add r11,r3,r11 #a + 8*i 65 0068 7CA72040 cmpld cr1,r7,r4 # if (i < n 66 006c 40840018 bge cr1,L4 # && 67 0070 E92B0000 ld r9,0(r11) #a[i] 68 0074 E94B0008 ld r10,8(r11) #a[i+1] 69 0078 7CA95000 cmpd cr1,r9,r10 # a[i] < a[i+1]) 70 007c 40840008 bge cr1,L4 71 0080 38E70001 addi r7,r7,1 # i++; 72 0084 78EB1F24 L4: sldi r11,r7,3 #8*i 73 0088 7D23582A ldx r9,r3,r11 #a[i] 74 008c 7CA84800 cmpd cr1,r8,r9 # if (tmp >= a[i]) 75 0090 40840014 bge cr1,L5 # break; 76 0094 78AB1F24 sldi r11,r5,3 #8*k 77 0098 7D23592A stdx r9,r3,r11 # a[k] = a[i]; 78 009c 7CE53B78 mr r5,r7 # } // k = i 79 00a0 4BFFFFB0 b L3 80 00a4 78AB1F24 L5: sldi r11,r5,3 #8*k 81 00a8 7D03592A stdx r8,r3,r11 # a[k] = tmp; 82 00ac 4E800020 blr #} SPARC GAS heapSort.s page 1 1 ! Подреди във възходящ ред масив от %i1 (%i1 > 2) думи със знак, указани от %i0 2 ! Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 ! average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 /* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 { // най-големия възел в корена му 8 int i, tmp; 9 10 n--; // Премини към база 0 11 for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 i = 2 * k; // Ляв потомък 13 if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 i++; // левия и избери по-големия 15 if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 break; // на най-големия потомък, клонът е OK 17 a[k] = a[i]; // Иначе потомъкът застава на мястото 18 } // на родителя 19 a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 } // потомък, освен ако е по-голям от всички потомци 21 22 void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 { // Сортиращо дърво, heap, tas: пирамида 24 int i, tmp; 25 26 for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 for (i = n - 1; i > 0; i--) { 29 tmp = a[i]; // Размени местата на максимума 30 a[i] = a[0]; // и последния елемент на масива 31 a[0] = tmp; 32 downHeap(a, 0, i); // Препострой сортиращото дърво за 33 } // неотсортираната част от масива 34 } 35 */ 36 37 .global heapSort !void heapSort(int *a, int n) //%i0, %i1 38 heapSort: !{ int i, tmp; //%l2 (%i1), %l2 39 0000 9DE3BF50 save %sp,-176,%sp!http://docs.oracle.com/cd/E37838_01/pdf/E61063.pdf 40 0004 A5367001 srlx %i1,1,%l2 ! for (i = n / 2; i >= 0; i--) 41 0008 B2266001 sub %i1,1,%i1 !n-- 42 000c 40000012 L1: call DownHeap ! downHeap(a, i, n);//%i0,%l1,%i1 43 0010 A2100012 mov %l2,%l1 !i (ще се изпълни преди „call“!) 44 0014 A4A4A001 subcc %l2,1,%l2 ! // i--) 45 0018 1A6FFFFD bcc %xcc,L1 ! // i >= 0; 46 001c 01000000 nop 47 0020 E65E0000 L2: ldx [%i0],%l3 !a[0] for (i = n - 1; i > 0; i--) {// %i1 = i 48 0024 A12E7003 sllx %i1,3,%l0 !8*i 49 0028 E45E0010 ldx [%i0+%l0],%l2 ! tmp = a[i]; 50 002c E6760010 stx %l3,[%i0+%l0] ! a[i] = a[0]; 51 0030 E4760000 stx %l2,[%i0] ! a[0] = tmp; 52 0034 A2100000 clr %l1 !k = 0 53 0038 40000007 call DownHeap ! downHeap(a, 0, i);//%i0,%l1,%i1 54 003c B2266001 sub %i1,1,%i1 !i-- (n--; ще се изпълни преди „call“!) 55 0040 80A64000 cmp %i1,%g0 56 0044 126FFFF7 bne %xcc,L2 ! } // i > 0 57 0048 01000000 nop 58 004c 81CFE008 return %i7+8 !} 59 0050 01000000 nop 60 0054 A12C7003 DownHeap: sllx %l1,3,%l0 !8*k void downHeap(int *a, int k, int n)//%i0,%l1,%i1 61 0058 E85E0010 ldx [%i0+%l0],%l4!tmp=a[k]{ int i,tmp;/*%l3,4 */n--;//вече намалено 62 005c A1367001 L3: srlx %i1,1,%l0 !n / 2 for (tmp = a[k]; k <= n / 2; k = i) { 63 0060 80A44010 cmp %l1,%l0 !k <= n / 2 ? 64 0064 18680014 bgu %xcc,L5 !ако не, край на цикъла 65 0068 A72C7001 sllx %l1,1,%l3 ! i = 2 * k; 66 006c A12CF003 sllx %l3,3,%l0 !8*i 67 0070 80A4C019 cmp %l3,%i1 ! if (i < n 68 0074 1A680008 bcc %xcc,L4 ! && 69 0078 A0060010 add %i0,%l0,%l0 !a + 8*i (ще се изпълни преди „bcc“!) 70 007c EA5C0000 ldx [%l0],%l5 !a[i] 71 0080 EC5C2008 ldx [%l0+8],%l6 !a[i+1] 72 0084 80A54016 cmp %l5,%l6 ! a[i] < a[i+1]) 73 0088 16680003 bge %xcc,L4 74 008c 01000000 nop 75 0090 A604E001 add %l3,1,%l3 ! i++; 76 0094 A12CF003 L4: sllx %l3,3,%l0 !8*i 77 0098 EA5E0010 ldx [%i0+%l0],%l5 !a[i] 78 009c 80A50015 cmp %l4,%l5 ! if (tmp >= a[i]) 79 00a0 16680006 bge %xcc,L6 ! break; 80 00a4 A12C7003 sllx %l1,3,%l0 !8*k (изпълнява се преди „bge“!) 81 00a8 EA760010 stx %l5,[%i0+%l0] ! a[k] = a[i]; 82 00ac A2100013 mov %l3,%l1 ! } // k = i 83 00b0 10BFFFEB ba L3 84 00b4 A12C7003 L5: sllx %l1,3,%l0 !8*k 85 00b8 81C3E008 L6: retl 86 00bc E8760010 stx %l4,[%i0+%l0] ! a[k] = tmp; }// изпълн.се преди „retl“! MIPS LISTING heapSort.s page 1 1 # Подреди във възходящ ред масив от $5 ($5 > 2) думи със знак, указани от $4 2 # Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 # average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 #/* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 #void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 #{ // най-големия възел в корена му 8 # int i, tmp; 9 # 10 # n--; // Премини към база 0 11 # for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 # i = 2 * k; // Ляв потомък 13 # if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 # i++; // левия и избери по-големия 15 # if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 # break; // на най-големия потомък, клонът е OK 17 # a[k] = a[i]; // Иначе потомъкът застава на мястото 18 # } // на родителя 19 # a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 #} // потомък, освен ако е по-голям от всички потомци 21 # 22 #void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 #{ // Сортиращо дърво, heap, tas: пирамида 24 # int i, tmp; 25 # 26 # for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 # downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 # for (i = n - 1; i > 0; i--) { 29 # tmp = a[i]; // Размени местата на максимума 30 # a[i] = a[0]; // и последния елемент на масива 31 # a[0] = tmp; 32 # downHeap(a, 0, i); // Препострой сортиращото дърво за 33 # } // неотсортираната част от масива 34 #} 35 #*/ 36 37 .ent heapSort 38 .global heapSort #void heapSort(int *a, int n) // $4, $5 39 heapSort: #{ int i, tmp; // $7 ($5), $7 40 0000 03E01025 MOVE $2,$31 #Съхрани $31, защото BAL ще го промени! 41 0004 0005387A DSRL $7,$5,1 # for (i = n / 2; i >= 0; i--) 42 0008 64A5FFFF DADDIU $5,$5,-1 #n-- 43 L1: MOVE $6,$7 #i 44 000c 04110011 00E03025 BAL DownHeap # downHeap(a, i, n); // $4,$6,$5 45 0014 64E7FFFF DADDIU $7,$7,-1 # // i--) 46 0018 04E1FFFC 00000000 BGE $7,$0,L1 # // i >= 0; 47 0020 DC880000 L2: LD $8,0($4) #a[0] for (i = n - 1; i > 0; i--) { // $5 = i 48 0024 000518F8 DSLL $3,$5,3 #8*i 49 0028 0083182D DADDU $3,$4,$3 #a + 8*i 50 002c DC670000 LD $7,0($3) # tmp = a[i]; 51 0030 FC680000 SD $8,0($3) # a[i] = a[0]; 52 0034 FC870000 SD $7,0($4) # a[0] = tmp; 53 0038 24060000 LI $6,0 #k = 0 54 DADDIU $5,$5,-1 #i-- (n--) 55 003c 04110005 64A5FFFF BAL DownHeap # downHeap(a, 0, i); // $4,$6,$5 56 0044 14A0FFF6 00000000 BNE $5,$0,L2 # } // i > 0 57 004c 00400008 00000000 JR $2 #} 58 0054 000618F8 DownHeap:DSLL $3,$6,3 #8*k void downHeap(int *a, int k, int n)// $4,$6,$5 59 0058 0083182D DADDU $3,$4,$3 #a + 8*k{ 60 005c DC690000 LD $9,0($3) #tmp=a[k] int i,tmp;/* $8,9 */n--;//вече намалено 61 0060 0005187A L3: DSRL $3,$5,1 #n / 2 for (tmp = a[k]; k <= n / 2; k = i) { 62 0064 0066082A 14200018 00000000 BGT $6,$3,L5 #k <= n / 2? 63 0070 00064078 DSLL $8,$6,1 # i = 2 * k; 64 0074 000818F8 DSLL $3,$8,3 #8*i 65 0078 0083182D DADDU $3,$4,$3 #a + 8*i 66 007c 0105082A 10200007 00000000 BGE $8,$5,L4 # if (i < n 67 0088 DC6A0000 LD $10,0($3) #a[i] && 68 008c DC6B0008 LD $11,8($3) #a[i+1] 69 0090 014B082A 10200002 00000000 BGE $10,$11,L4 # a[i] < a[i+1]) 70 009c 65080001 DADDIU $8,$8,1 # i++; 71 00a0 000818F8 L4: DSLL $3,$8,3 #8*i 72 00a4 0083182D DADDU $3,$4,$3 #a + 8*i 73 00a8 DC6A0000 LD $10,0($3) #a[i] if (tmp >= a[i]) 74 00ac 012A082A 10200006 00000000 BGE $9,$10,L5 # break; 75 00b8 000618F8 DSLL $3,$6,3 #8*k 76 00bc 0083182D DADDU $3,$4,$3 #a + 8*k 77 00c0 FC6A0000 SD $10,0($3) # a[k] = a[i]; 78 MOVE $6,$8 # } // k = i 79 00c4 1000FFE6 01003025 B L3 80 00cc 000618F8 L5: DSLL $3,$6,3 #8*k 81 00d0 0083182D DADDU $3,$4,$3 #a + 8*k 82 SD $9,0($3) # a[k] = tmp; 83 00d4 03E00008 FC690000 JR $31 #} 84 00dc 00000000 .end heapSort RISC-V LISTING heapSort.s page 1 1 # Подреди във възходящ ред масив от a1 (a1 > 2) думи със знак, указани от a0 2 # Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 # average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 /* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 { // най-големия възел в корена му 8 int i, tmp; 9 10 n--; // Премини към база 0 11 for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 i = 2 * k; // Ляв потомък 13 if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 i++; // левия и избери по-големия 15 if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 break; // на най-големия потомък, клонът е OK 17 a[k] = a[i]; // Иначе потомъкът застава на мястото 18 } // на родителя 19 a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 } // потомък, освен ако е по-голям от всички потомци 21 22 void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 { // Сортиращо дърво, heap, tas: пирамида 24 int i, tmp; 25 26 for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 for (i = n - 1; i > 0; i--) { 29 tmp = a[i]; // Размени местата на максимума 30 a[i] = a[0]; // и последния елемент на масива 31 a[0] = tmp; 32 downHeap(a, 0, i); // Препострой сортиращото дърво за 33 } // неотсортираната част от масива 34 } 35 */ 36 37 .global heapSort #void heapSort(int *a, int n) // a0, a1 38 heapSort: #{ int i, tmp; // a3 (a1), a3 39 0000 93D61500 SRLI a3,a1,1 # for (i = n / 2; i >= 0; i--) 40 0004 9385F5FF ADDI a1,a1,-1 #n-- 41 0008 13860600 L1: MV a2,a3 #i 42 000c EF028003 JAL t0,DownHeap # downHeap(a, i, n); // a0,a2,a1 43 0010 9386F6FF ADDI a3,a3,-1 # // i--) 44 0014 E3DA06FE BGEZ a3,L1 # // i >= 0; 45 0018 03370500 L2: LD a4,0(a0) #a[0] for (i = n - 1; i > 0; i--) { // a1 = i 46 001c 13933500 SLLI t1,a1,3 #8*i 47 0020 33036500 ADD t1,a0,t1 #a + 8*i 48 0024 83360300 LD a3,0(t1) # tmp = a[i]; 49 0028 2330E300 SD a4,0(t1) # a[i] = a[0]; 50 002c 2330D500 SD a3,0(a0) # a[0] = tmp; 51 0030 13060000 LI a2,0 #k = 0 52 0034 9385F5FF ADDI a1,a1,-1 #i-- (n--) 53 0038 EF02C000 JAL t0,DownHeap # downHeap(a, 0, i); // a0,a2,a1 54 003c E39E05FC BNEZ a1,L2 # } // i > 0 55 0040 67800000 RET #} 56 0044 13133600 DownHeap: SLLI t1,a2,3 #8*k void downHeap(int *a, int k, int n)// a0,a2,a1 57 0048 33036500 ADD t1,a0,t1 #a + 8*k{ 58 004c 83370300 LD a5,0(t1) #tmp=a[k] int i,tmp;/* a4,5 */n--;//вече намалено 59 0050 13D31500 L3: SRLI t1,a1,1 #n / 2 for (tmp = a[k]; k <= n / 2; k = i) { 60 0054 6344C304 BGT a2,t1,L5 #k <= n / 2? 61 0058 13171600 SLLI a4,a2,1 # i = 2 * k; 62 005c 13133700 SLLI t1,a4,3 #8*i 63 0060 33036500 ADD t1,a0,t1 #a + 8*i 64 0064 635AB700 BGE a4,a1,L4 # if (i < n 65 0068 03380300 LD a6,0(t1) #a[i] && 66 006c 83388300 LD a7,8(t1) #a[i+1] 67 0070 63541801 BGE a6,a7,L4 # a[i] < a[i+1]) 68 0074 13071700 ADDI a4,a4,1 # i++; 69 0078 13133700 L4: SLLI t1,a4,3 #8*i 70 007c 33036500 ADD t1,a0,t1 #a + 8*i 71 0080 03380300 LD a6,0(t1) #a[i] if (tmp >= a[i]) 72 0084 63DC0701 BGE a5,a6,L5 # break; 73 0088 13133600 SLLI t1,a2,3 #8*k 74 008c 33036500 ADD t1,a0,t1 #a + 8*k 75 0090 23300301 SD a6,0(t1) # a[k] = a[i]; 76 0094 13060700 MV a2,a4 # } // k = i 77 0098 6FF09FFB J L3 78 009c 13133600 L5: SLLI t1,a2,3 #8*k 79 00a0 33036500 ADD t1,a0,t1 #a + 8*k 80 00a4 2330F300 SD a5,0(t1) # a[k] = tmp; 81 00a8 67800200 JR t0 #} LOONGARCH64 GAS heapSort.s page 1 1 # Подреди във възходящ ред масив от r5 (r5 > 2) думи със знак, указани от r4 2 # Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 # average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 #/* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 #void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 #{ // най-големия възел в корена му 8 # int i, tmp; 9 # 10 # n--; // Премини към база 0 11 # for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 # i = 2 * k; // Ляв потомък 13 # if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 # i++; // левия и избери по-големия 15 # if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 # break; // на най-големия потомък, клонът е OK 17 # a[k] = a[i]; // Иначе потомъкът застава на мястото 18 # } // на родителя 19 # a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 #} // потомък, освен ако е по-голям от всички потомци 21 # 22 #void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 #{ // Сортиращо дърво, heap, tas: пирамида 24 # int i, tmp; 25 # 26 # for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 # downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 # for (i = n - 1; i > 0; i--) { 29 # tmp = a[i]; // Размени местата на максимума 30 # a[i] = a[0]; // и последния елемент на масива 31 # a[0] = tmp; 32 # downHeap(a, 0, i); // Препострой сортиращото дърво за 33 # } // неотсортираната част от масива 34 #} 35 #*/ 36 37 .global heapSort #void heapSort(int *a, int n) // r4, r5 38 heapSort: #{ int i, tmp; // r7 (r5), r7 39 0000 2C001500 OR $r12,$r1,$r0 #Съхрани r1, защото BL ще го промени! 40 0004 A7044500 SRLI.D $r7,$r5,1 # for (i = n / 2; i >= 0; i--) 41 0008 A5FCFF02 ADDI.D $r5,$r5,-1 #n-- 42 000c E6001500 L1: OR $r6,$r7,$r0 #i 43 0010 00340054 BL DownHeap # downHeap(a, i, n); // r4,r6,r5 44 0014 E7FCFF02 ADDI.D $r7,$r7,-1 # // i--) 45 0018 E0F4FF67 BGEZ $r7,L1 # // i >= 0; 46 001c 8800C028 L2: LD.D $r8,$r4,0 #a[0] for (i = n - 1; i > 0; i--) { // r5 = i 47 0020 AD102D00 ALSL.D $r13,$r5,$r4,3 #a + 8*i 48 0024 A701C028 LD.D $r7,$r13,0 # tmp = a[i]; 49 0028 A801C029 ST.D $r8,$r13,0 # a[i] = a[0]; 50 002c 8700C029 ST.D $r7,$r4,0 # a[0] = tmp; 51 0030 06001500 OR $r6,$r0,$r0 #k = 0 52 0034 A5FCFF02 ADDI.D $r5,$r5,-1 #i-- (n--) 53 0038 000C0054 BL DownHeap # downHeap(a, 0, i); // r4,r6,r5 54 003c BFE0FF47 BNEZ $r5,L2 # } // i > 0 55 0040 8001004C JIRL $r0,$r12,0 #}void downHeap(int *a, int k, int n)//r4,r6,r5 56 0044 CD102D00 DownHeap:ALSL.D $r13,$r6,$r4,3#a + 8*k{ 57 0048 A901C028 LD.D $r9,$r13,0 #tmp=a[k] int i,tmp;/* r8,9 */n--;//вече намалено 58 004c AD044500 L3: SRLI.D $r13,$r5,1 #n / 2 for (tmp = a[k]; k <= n / 2; k = i) { 59 0050 A63D0060 BGT $r6,$r13,L5#k <= n / 2? 60 0054 C8044100 SLLI.D $r8,$r6,1 # i = 2 * k; 61 0058 0D112D00 ALSL.D $r13,$r8,$r4,3 #a + 8*i 62 005c 05150064 BGE $r8,$r5,L4 # if (i < n 63 0060 AA01C028 LD.D $r10,$r13,0 #a[i] && 64 0064 AB21C028 LD.D $r11,$r13,8 #a[i+1] 65 0068 4B090064 BGE $r10,$r11,L4 # a[i] < a[i+1]) 66 006c 0805C002 ADDI.D $r8,$r8,1 # i++; 67 0070 0D112D00 L4: ALSL.D $r13,$r8,$r4,3 #a + 8*i 68 0074 AA01C028 LD.D $r10,$r13,0 #a[i] if (tmp >= a[i]) 69 0078 2A150064 BGE $r9,$r10,L5 # break; 70 007c CD102D00 ALSL.D $r13,$r6,$r4,3 #a + 8*k 71 0080 AA01C029 ST.D $r10,$r13,0 # a[k] = a[i]; 72 0084 06011500 OR $r6,$r8,$r0 # } // k = i 73 0088 FFC7FF53 B L3 74 008c CD102D00 L5: ALSL.D $r13,$r6,$r4,3 #a + 8*k 75 0090 A901C029 ST.D $r9,$r13,0 # a[k] = tmp; 76 0094 2000004C JIRL $r0,$r1,0 #} # Подреди във възходящ ред масив от $17 ( > 2) думи със знак, указани от $16 # Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an # average, Quicksort (if n is not very small), Theoretical Comp. Science '93 #/* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. #void downHeap(int *a, int k, int n) // Прегледай поддървото и премести #{ // най-големия възел в корена му # int i, tmp; # # n--; // Премини към база 0 # for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя # i = 2 * k; // Ляв потомък # if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с # i++; // левия и избери по-големия # if (tmp >= a[i]) // Ако родителят е по-голям или равен # break; // на най-големия потомък, клонът е OK # a[k] = a[i]; // Иначе потомъкът застава на мястото # } // на родителя # a[k] = tmp; // Накрая родителят си разменя мястото с най-големия #} // потомък, освен ако е по-голям от всички потомци # #void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) #{ // Сортиращо дърво, heap, tas: пирамида # int i, tmp; # # for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният # downHeap(a, i, n); // елемент на масива ще бъде в корена) # for (i = n - 1; i > 0; i--) { # tmp = a[i]; // Размени местата на максимума # a[i] = a[0]; // и последния елемент на масива # a[0] = tmp; # downHeap(a, 0, i); // Препострой сортиращото дърво за # } // неотсортираната част от масива #} heapSort.o: file format ecoff-littlealpha #*/ Disassembly of section .text: .ent heapSort .globl heapSort #void heapSort(int *a, int n) // $16, $17 0000000000000000 : heapSort: #{ int i, tmp; // $7 ($17), $7 0: 87 36 20 4a srl a1,0x1,t6 bis $31,$26,$2 #Съхрани $26, защото „bsr“ ще го промени! 4: 02 04 fa 47 mov ra,t1 srl $17,1,$7 # for (i = n / 2; i >= 0; i--) 8: 31 35 20 42 subq a1,0x1,a1 subq $17,1,$17 #n-- c: 06 04 e7 47 mov t6,t5 L1: bis $31,$7,$6 #i 10: 0d 00 40 d3 bsr ra,48 bsr DownHeap # downHeap(a, i, n); //$16,$6,$17 14: 27 35 e0 40 subq t6,0x1,t6 subq $7,1,$7 # // i--) 18: fc ff ff f8 bge t6,c bge $7,L1 # // i >= 0; 1c: 43 06 30 42 s8addq a1,a0,t2 L2: ldq $8,0($16) #a[0] for (i = n - 1; i > 0; i--) { //$17 = i 20: 00 00 10 a5 ldq t7,0(a0) s8addq $17,$16,$3 #a + 8*i 24: 31 35 20 42 subq a1,0x1,a1 ldq $7,0($3) # tmp = a[i]; 28: 00 00 e3 a4 ldq t6,0(t2) stq $8,0($3) # a[i] = a[0]; 2c: 06 04 ff 47 clr t5 stq $7,0($16) # a[0] = tmp; 30: 00 00 03 b5 stq t7,0(t2) bis $31,$31,$6 #k = 0 34: 00 00 f0 b4 stq t6,0(a0) subq $17,1,$17 #i-- (n--) 38: 03 00 40 d3 bsr ra,48 bsr DownHeap # downHeap(a, 0, i); //$16,$6,$17 3c: f7 ff 3f f6 bne a1,1c bne $17,L2 # } // i > 0 40: 1a 04 e2 47 mov t1,ra bis $31,$2,$26 #} 44: 01 80 fa 6b ret zero,(ra),0x1 ret #void downHeap(int *a, int k,int n)//$16,$6,$17 48: 43 06 d0 40 s8addq t5,a0,t2 DownHeap:s8addq $6,$16,$3#a + 8*k{ 4c: 00 00 83 a4 ldq t3,0(t2) ldq $4,0($3) #tmp=a[k] int i,tmp;/* $8,4 */n--;//вече намалено 50: 83 36 20 4a srl a1,0x1,t2 L3: srl $17,1,$3 #n / 2 for (tmp = a[k]; k <= n / 2; k = i) { 54: a5 07 c3 40 cmpule t5,t2,t4 cmpule $6,$3,$5 #k <= n / 2? 58: 11 00 a0 e4 beq t4,a0 beq $5,L5 5c: 08 04 c6 40 addq t5,t5,t7 sll $6,1,$8 # i = 2 * k; 60: 43 06 10 41 s8addq t7,a0,t2 s8addq $8,$16,$3 #a + 8*i 64: a5 03 11 41 cmpult t7,a1,t4 cmpult $8,$17,$5 # if (i < n 68: 05 00 a0 e4 beq t4,80 beq $5,L4 6c: 00 00 03 a4 ldq v0,0(t2) ldq $0,0($3) #a[i] && 70: 08 00 23 a4 ldq t0,8(t2) ldq $1,8($3) #a[i+1] 74: a5 09 01 40 cmplt v0,t0,t4 cmplt $0,$1,$5 # a[i] < a[i+1]) 78: 01 00 a0 e4 beq t4,80 beq $5,L4 7c: 08 34 00 41 addq t7,0x1,t7 addq $8,1,$8 # i++; 80: 43 06 10 41 s8addq t7,a0,t2 L4: s8addq $8,$16,$3 #a + 8*i 84: 00 00 03 a4 ldq v0,0(t2) ldq $0,0($3) #a[i] if (tmp >= a[i]) 88: a5 0d 04 40 cmple v0,t3,t4 cmple $0,$4,$5 # break; 8c: 04 00 a0 f4 bne t4,a0 bne $5,L5 90: 43 06 d0 40 s8addq t5,a0,t2 s8addq $6,$16,$3 #a + 8*k 94: 06 04 e8 47 mov t7,t5 stq $0,0($3) # a[k] = a[i]; 98: 00 00 03 b4 stq v0,0(t2) bis $31,$8,$6 # } // k = i 9c: ec ff ff c3 br 50 br $31,L3 a0: 43 06 d0 40 s8addq t5,a0,t2 L5: s8addq $6,$16,$3 #a + 8*k a4: 00 00 83 b4 stq t3,0(t2) stq $4,0($3) # a[k] = tmp; a8: 01 80 fa 6b ret zero,(ra),0x1 ret #} ac: 1f 04 ff 47 nop .end heapSort GAS for MMIX heapSort.s page 1 1 % Подреди във възходящ ред масив от $1 ( > 2) думи със знак, указани от $0 2 % Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 % average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 %/* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 %void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 %{ // най-големия възел в корена му 8 % int i, tmp; 9 % 10 % n--; // Премини към база 0 11 % for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 % i = 2 * k; // Ляв потомък 13 % if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 % i++; // левия и избери по-големия 15 % if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 % break; // на най-големия потомък, клонът е OK 17 % a[k] = a[i]; // Иначе потомъкът застава на мястото 18 % } // на родителя 19 % a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 %} // потомък, освен ако е по-голям от всички потомци 21 % 22 %void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 %{ // Сортиращо дърво, heap, tas: пирамида 24 % int i, tmp; 25 % 26 % for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 % downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 % for (i = n - 1; i > 0; i--) { 29 % tmp = a[i]; // Размени местата на максимума 30 % a[i] = a[0]; // и последния елемент на масива 31 % a[0] = tmp; 32 % downHeap(a, 0, i); // Препострой сортиращото дърво за 33 % } // неотсортираната част от масива 34 %} 35 %*/ 36 37 .global heapSort %void heapSort(int *a, int n) // $0, $1 38 heapSort: %{ int i, tmp; // $7 ($1), $7 39 0000 3F070101 SRU $7,$1,1 % for (i = n / 2; i >= 0; i--) 40 0004 27010101 SUBU $1,$1,1 %n-- 41 0008 C1060700 L1: OR $6,$7,0 %i 42 000c F4020002 GETA $2,@+8 43 0010 F000000E JMP DownHeap % downHeap(a, i, n); //$0, $6, $1 44 0014 27070701 SUBU $7,$7,1 % // i--) 45 0018 4907FFFC BNN $7,L1 % // i >= 0; 46 001c 8D080000 L2: LDO $8,$0,0 %a[0] for (i = n - 1; i > 0; i--) { //$1 = i 47 0020 2C030100 8ADDU $3,$1,$0 %a + 8*i 48 0024 8D070300 LDO $7,$3,0 % tmp = a[i]; 49 0028 AD080300 STO $8,$3,0 % a[i] = a[0]; 50 002c AD070000 STO $7,$0,0 % a[0] = tmp; 51 0030 C6060606 XOR $6,$6,$6 %k = 0 52 0034 27010101 SUBU $1,$1,1 %i-- (n--) 53 0038 F4020002 GETA $2,@+8 54 003c F0000003 JMP DownHeap % downHeap(a, 0, i); //$0, $6, $1 55 0040 4B01FFF7 BNZ $1,L2 % } // i > 0 56 0044 F8000000 POP 0,0 %}void downHeap(int *a, int k,int n)//$0,$6, $1 57 0048 2C030600 DownHeap: 8ADDU $3,$6,$0 %a + 8*k{ 58 004c 8D040300 LDO $4,$3,0 %tmp=a[k] int i,tmp;/* $8,4 */n--;//вече намалено 59 0050 3F030101 L3: SRU $3,$1,1 %n / 2 for (tmp = a[k]; k <= n / 2; k = i) { 60 0054 32050603 CMPU $5,$6,$3 %k <= n / 2? 61 0058 44050012 BP $5,L5 62 005c 3B080601 SLU $8,$6,1 % i = 2 * k; 63 0060 2C030800 8ADDU $3,$8,$0 %a + 8*i 64 0064 32050801 CMPU $5,$8,$1 % if (i < n 65 0068 48050006 BNN $5,L4 66 006c 8D090300 LDO $9,$3,0 %a[i] && 67 0070 8D0A0308 LDO $10,$3,8 %a[i+1] 68 0074 3005090A CMP $5,$9,$10 % a[i] < a[i+1]) 69 0078 48050002 BNN $5,L4 70 007c 23080801 ADDU $8,$8,1 % i++; 71 0080 2C030800 L4: 8ADDU $3,$8,$0 %a + 8*i 72 0084 8D090300 LDO $9,$3,0 %a[i] if (tmp >= a[i]) 73 0088 30050409 CMP $5,$4,$9 % break; 74 008c 48050005 BNN $5,L5 75 0090 2C030600 8ADDU $3,$6,$0 %a + 8*k 76 0094 AD090300 STO $9,$3,0 % a[k] = a[i]; 77 0098 C1060800 OR $6,$8,0 % } // k = i 78 009c F1FFFFED JMP L3 79 00a0 2C030600 L5: 8ADDU $3,$6,$0 %a + 8*k 80 00a4 AD040300 STO $4,$3,0 % a[k] = tmp; 81 00a8 9F020200 GO $2,$2,0 %} HPPA64 LISTING heapSort.s page 1 1 ; Подреди във възходящ ред масив от R25 (R25 > 2) думи със знак, указани от R26 2 ; Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 ; average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 /* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 { // най-големия възел в корена му 8 int i, tmp; 9 10 n--; // Премини към база 0 11 for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 i = 2 * k; // Ляв потомък 13 if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 i++; // левия и избери по-големия 15 if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 break; // на най-големия потомък, клонът е OK 17 a[k] = a[i]; // Иначе потомъкът застава на мястото 18 } // на родителя 19 a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 } // потомък, освен ако е по-голям от всички потомци 21 22 void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 { // Сортиращо дърво, heap, tas: пирамида 24 int i, tmp; 25 26 for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 for (i = n - 1; i > 0; i--) { 29 tmp = a[i]; // Размени местата на максимума 30 a[i] = a[0]; // и последния елемент на масива 31 a[0] = tmp; 32 downHeap(a, 0, i); // Препострой сортиращото дърво за 33 } // неотсортираната част от масива 34 } 35 */ 36 .global heapSort ; void heapSort(int *a, int n) //R26, R25 37 heapSort: ; { | int i, tmp; //R23 (25), R23 38 0000 D3200FD7 SHRPD %R0,%R25,1,%R23 ; | for (i = n / 2; i >= 0; i--) 39 0004 B73907FF ADDI -1,%R25,%R25 ; n-- | 40 0008 EBE00060 L1: B,L DOWNHEAP,%R31;изп.се след COPY downHeap(a, i, n); //26,22,25 41 000c 08170256 COPY %R23,%R22 ; i | 42 0010 AEFF5FE5 ADDIB,>= -1,%R23,L1 ;изп.се след LDI;*>=??// i >= 0; i--) 43 0014 34160000 L2: LDI 0,%R22 ; k = 0 | for (i = n - 1; i > 0; i--) {//R25: i 44 0018 0B590ADC SHLADD,L %R25,3,%R26,%R28;адр.отм. 45 001c 0F8010D7 LDD 0(%R28),%R23 ; | tmp = a[i]; 46 0020 0F4010DD LDD 0(%R26),%R29 ; =a[0] | a[i] = a[0]; 47 0024 0F5712C0 STD %R23,0(%R26) ; | a[0] = tmp; 48 0028 0F9D12C0 STD %R29,0(%R28) ; a[i]= | 49 002c EBE00018 B,L DOWNHEAP,%R31;изп.се след ADDI downHeap(a, 0, i); //26,22,25 50 0030 B73907FF ADDI -1,%R25,%R25 ; i(n)--| // i > 0; 51 0034 EF20BFB5 CMPIB,*<> 0,%R25,L2 ; | } 52 0038 08000240 NOP ; } 53 003c E840D002 BVE,N (%R2) ; void downHeap(int *a, int k, int n)//26,22,25 54 0040 0F5620C1 DOWNHEAP: LDD,S %R22(%R26),%R1 ; { | int i,tmp;/*24,1*/n--;//вече намалено 55 0044 D3200FD5 L3: SHRPD %R0,%R25,1,%R21 ; | for (tmp = a[k]; k <= n / 2; k = i) { 56 0048 BEB66060 CMPB,*> %R22,%R21,L5 ; | // k <= n / 2 57 004c 08160A58 SHLADD,L %R22,1,%R0,%R24;изп.се предиCMPB i = 2 * k; 58 0050 BF384020 CMPB,*>= %R24,%R25,L4 ; i и n < 2^63 if (i < n && 59 0054 0B580AD5 SHLADD,L %R24,3,%R26,%R21;изп.се преди CMPB 60 0058 0EA010D4 LDD 0(%R21),%R20 ; a[i] | 61 005c 0EB010D3 LDD 8(%R21),%R19 ; a[i+1]| 62 0060 0A7458A0 CMPCLR,*>= %R20,%R19,%R0; | a[i] < a[i+1]) 63 0064 B7180002 ADDI 1,%R24,%R24 ; | i++; 64 0068 0F5820D4 L4: LDD,S %R24(%R26),%R20 ; a[i] | 65 006c 9C346018 CMPB,*<= %R20,%R1,L5 ; | if (tmp >= a[i]) break; 66 0070 0B560AD5 SHLADD,L %R22,3,%R26,%R21;изп.се преди CMPB 67 0074 0EB412C0 STD %R20,0(%R21) ; | a[k] = a[i]; 68 0078 08180256 COPY %R24,%R22 ; k = i | } 69 007c E81F1F87 B,N L3 ; | 70 0080 0B560AD5 L5: SHLADD,L %R22,3,%R26,%R21;адр.отм. 71 0084 0EA112C0 STD %R1,0(%R21) ; | a[k] = tmp; 72 0088 EBE0D002 BVE,N (%R31) ; } TILE-Gx GAS heapSort.s page 1 1 # Подреди във възходящ ред масив от r1 ( > 2) думи със знак, указани от r0 2 # Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 # average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 #/* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 #void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 #{ // най-големия възел в корена му 8 # int i, tmp; 9 # 10 # n--; // Премини към база 0 11 # for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 # i = 2 * k; // Ляв потомък 13 # if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 # i++; // левия и избери по-големия 15 # if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 # break; // на най-големия потомък, клонът е OK 17 # a[k] = a[i]; // Иначе потомъкът застава на мястото 18 # } // на родителя 19 # a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 #} // потомък, освен ако е по-голям от всички потомци 21 # 22 #void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 #{ // Сортиращо дърво, heap, tas: пирамида 24 # int i, tmp; 25 # 26 # for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 # downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 # for (i = n - 1; i > 0; i--) { 29 # tmp = a[i]; // Размени местата на максимума 30 # a[i] = a[0]; // и последния елемент на масива 31 # a[0] = tmp; 32 # downHeap(a, 0, i); // Препострой сортиращото дърво за 33 # } // неотсортираната част от масива 34 #} 35 #*/ 36 37 .global heapSort #void heapSort(int *a, int n) // r0, r1 38 heapSort: #{ int i, tmp; // r9 (r1), r9 39 { MOVE r4,lr #Съхрани lr, защото „JAL“ ще го промени! 40 0000 C4FD07D1 24080A30 SHRUI r9,r1,1 } # for (i = n / 2; i >= 0; i--) 41 0008 003048D1 20F80F18 ADDI r1,r1,-1 #n-- 42 0010 00304851 24F93B28 L1: MOVE r8,r9 #i 43 { JAL DownHeap # downHeap(a, i, n); //r0,r8,r1 44 0018 49F21FC0 04000020 ADDI r9,r9,-1 } # // i--) 45 0020 00304851 3FF9BF14 BGEZT r9,L1 # // i >= 0; 46 L2: { LD r10,r0 #a[0] for (i = n - 1; i > 0; i--) { //r1 = i 47 0028 45000834 0040569E SHL3ADD r5,r1,r0 } #a + 8*i 48 0030 00305C34 00404E9E LD r9,r5 # tmp = a[i]; 49 0038 00305C34 004056DE ST r5,r10 # a[i] = a[0]; 50 { ST r0,r9 # a[0] = tmp; 51 MOVE r8,zero #k = 0 52 0040 C8FF0BD4 20F84FC6 ADDI r1,r1,-1 } #i-- (n--) 53 0048 003048D1 01000020 JAL DownHeap # downHeap(a, 0, i); //r0,r8,r1 54 0050 003048D1 3DF8BF17 BNEZT r1,L2 # } // i > 0 55 0058 00304851 80706A28 JR r4 #}void downHeap(int *a, int k,int n)//r0,r8,r1 56 0060 003048D1 02014828 DownHeap:SHL3ADD r5,r8,r0#a + 8*k{ 57 0068 00305C34 0040369E LD r6,r5 #tmp=a[k] int i,tmp;/*r10,r6*/n--;//вече намалено 58 0070 003048D1 22080A30 L3: SHRUI r5,r1,1 #n / 2 for (tmp = a[k]; k <= n / 2; k = i) { 59 0078 003048D1 03291228 CMPLEU r7,r8,r5 #k <= n / 2? 60 { BEQZ r7,L5 61 0080 0A120860 E7004014 SHLI r10,r8,1 } # i = 2 * k; 62 { SHL3ADD r5,r10,r0 #a + 8*i 63 0088 850220D1 43091628 CMPLTU r7,r10,r1 } # if (i < n 64 0090 00304851 E3004014 BEQZ r7,L4 65 0098 00304851 A140A018 LD_ADD r2,r5,8 #a[i] && 66 00a0 00305C34 00401E9E LD r3,r5 #a[i+1] 67 00a8 003048D1 43181428 CMPLTS r7,r2,r3 # a[i] < a[i+1]) 68 00b0 00304851 E1004014 BEQZ r7,L4 69 00b8 00304851 45090818 ADDI r10,r10,1 # i++; 70 00c0 003048D1 42014828 L4: SHL3ADD r5,r10,r0 #a + 8*i 71 00c8 00305C34 0040169E LD r2,r5 #a[i] if (tmp >= a[i]) 72 00d0 003048D1 43301028 CMPLES r7,r2,r6 # break; 73 { BNEZ r7,L5 74 00d8 050220D1 E100C017 SHL3ADD r5,r8,r0 } #a + 8*k 75 { ST r5,r2 # a[k] = a[i]; 76 00e0 88F25B54 004016DE MOVE r8,r10 } # } // k = i 77 00e8 003048D1 F8FFFF27 J L3 78 00f0 003048D1 02014828 L5: SHL3ADD r5,r8,r0 #a + 8*k 79 { ST r5,r6 # a[k] = tmp; 80 00f8 00305C34 E06E36DE JR lr } #} IA-64 GAS heapSort.s page 1 1 // Подреди във възходящ ред масив от in1 ( > 2) думи със знак, указани от in0 2 // Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 // average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 ///* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 //void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 //{ // най-големия възел в корена му 8 // int i, tmp; 9 // 10 // n--; // Премини към база 0 11 // for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 // i = 2 * k; // Ляв потомък 13 // if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 // i++; // левия и избери по-големия 15 // if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 // break; // на най-големия потомък, клонът е OK 17 // a[k] = a[i]; // Иначе потомъкът застава на мястото 18 // } // на родителя 19 // a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 //} // потомък, освен ако е по-голям от всички потомци 21 // 22 //void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 //{ // Сортиращо дърво, heap, tas: пирамида 24 // int i, tmp; 25 // 26 // for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 // downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 // for (i = n - 1; i > 0; i--) { 29 // tmp = a[i]; // Размени местата на максимума 30 // a[i] = a[0]; // и последния елемент на масива 31 // a[0] = tmp; 32 // downHeap(a, 0, i); // Препострой сортиращото дърво за 33 // } // неотсортираната част от масива 34 //} 35 //*/ 36 37 .global heapSort //void heapSort(int *a, int n) //in0, in1 38 heapSort: //{ int i, tmp; //r11 (in1),r11 39 ALLOC r2=ar.pfs,2,0,0,0//!!! 40 SHR.U r11=in1,1 // for (i = n / 2; i >= 0; i--) 41 SUB in1=in1,r0,1 //n-- 42 0000 01100804 8005B010 847C2920 14021080 L1: MOV r10=r11 //i 43 BR.CALL.SPTK b6=DownHeap// downHeap(a, i, n);//in0,r10,in1 44 SUB r11=r11,r0,1 // // i--) 45 0010 10500016 00210000 000200C0 90000050 CMP.GE p6,p7=r11,r0 // // i >= 0; 46 (p6) BR L1 47 0020 0A582C00 04207058 000C6000 00000400 L2: LD8 r8=[in0] //a[0] for (i = n - 1; i > 0; i--) { //in1 = i 48 SHLADD r3=in1,3,in0 //a + 8*i 49 0030 10000000 01000000 00020003 E0FFFF48 LD8 r11=[r3] // tmp = a[i]; 50 0040 02400040 18103008 81244000 00000400 ST8 [r3]=r8 // a[i] = a[0]; 51 ST8 [in0]=r11 // a[0] = tmp; 52 0050 09580006 18100040 0C302300 00000400 MOV r10=r0 //k = 0 53 SUB in1=in1,r0,1 //i-- (n--) 54 0060 00002C40 9811A000 00004220 14021080 BR.CALL.SPTK b6=DownHeap// downHeap(a, 0, i);//in0,r10,in1 55 CMP.NE p6,p7=in1,r0 // } // i > 0 56 (p6) BR L2 //} 57 0070 10000000 01000000 000200C0 30000050 MOV ar.pfs=r2 //!!! 58 0080 10388400 06380000 00020003 C0FFFF48 BR.RET.SPTK b0 //void downHeap(int*a,int k,int n)//in0,r10,in1 59 DownHeap:SHLADD r3=r10,3,in0//a+8*k{ 60 0090 10000000 01000010 00550080 00008400 LD8 r9=[r3] //tmp=a[k] int i,tmp;/* r8,9 */n--;//вече намалено 61 L3: SHR.U r3=in1,1 //n / 2 for (tmp = a[k]; k <= n / 2; k = i) { 62 00a0 0A182840 12209000 0C302000 00000400 CMP.LEU p6,p7=r10,r3//k <= n / 2? 63 (p7) BR.DPNT L4 64 00b0 02000000 01003010 847C29E0 305018D0 SHL r8=r10,1 // i = 2 * k; 65 SHLADD r3=r8,3,in0 //a+8*i 66 00c0 10000000 01000000 00028003 80000043 CMP.LTU p6,p7=r8,in1 // if (i < n 67 00d0 02000000 01008050 F8FC2960 80004980 (p6) LD8 r14=[r3],8 //a[i] && 68 (p6) LD8 r15=[r3] //a[i+1] 69 00e0 0B302042 07B4E140 0C302800 00000400 (p6) CMP.LT p6,p7=r14,r15 // a[i] < a[i+1]) 70 (p6) ADD r8=r8,r0,1 // i++; 71 00f0 CB780006 18906170 3C0E6000 00000400 SHLADD r3=r8,3,in0 //a+8*i 72 LD8 r14=[r3] //a[i] if (tmp >= a[i]) 73 0100 CB402000 01203040 80244000 00000400 CMP.GE p6,p7=r9,r14 // break; 74 (p7) SHLADD r3=r10,3,in0 //a+8*k 75 0110 0B700006 18107048 380C6000 00000400 (p7) ST8 [r3]=r14 // a[k] = a[i]; 76 (p7) MOV r10=r8 // } // k = i 77 0120 EA182840 12E00170 0C30A343 01400084 (p7) BR L3 78 L4: SHLADD r3=r10,3,in0 //a+8*k 79 ST8 [r3]=r9 // a[k] = tmp; 80 0130 10000000 01000000 00028003 80FFFF48 BR.RET.SPTK b6 //} 80 0A182840 12200048 0C302300 00000400 80 11000000 01000000 00020080 60008400 E2K GAS heapSort.s page 1 1 ! Подреди във възходящ ред масив от r1 ( > 2) думи със знак, указани от r0 2 ! Ingo Wegener: Bottom-up Heapsort, a new variant of Heapsort beating, on an 3 ! average, Quicksort (if n is not very small), Theoretical Comp. Science '93 4 5 /* Пирамида – двоично дърво, в което родителят е не по-малък от потомците си. 6 void downHeap(int *a, int k, int n) // Прегледай поддървото и премести 7 { // най-големия възел в корена му 8 int i, tmp; 9 10 n--; // Премини към база 0 11 for (tmp = a[k]; k <= n / 2; k = i) { // В корена запомни родителя 12 i = 2 * k; // Ляв потомък 13 if (i < n && a[i] < a[i+1]) // Ако има десен, сравни го с 14 i++; // левия и избери по-големия 15 if (tmp >= a[i]) // Ако родителят е по-голям или равен 16 break; // на най-големия потомък, клонът е OK 17 a[k] = a[i]; // Иначе потомъкът застава на мястото 18 } // на родителя 19 a[k] = tmp; // Накрая родителят си разменя мястото с най-големия 20 } // потомък, освен ако е по-голям от всички потомци 21 22 void heapSort(int *a, int n) // Пирамидално сортиране (tri par tas) 23 { // Сортиращо дърво, heap, tas: пирамида 24 int i, tmp; 25 26 for (i = n / 2; i >= 0; i--) // Създай сортиращо дърво (максималният 27 downHeap(a, i, n); // елемент на масива ще бъде в корена) 28 for (i = n - 1; i > 0; i--) { 29 tmp = a[i]; // Размени местата на максимума 30 a[i] = a[0]; // и последния елемент на масива 31 a[0] = tmp; 32 downHeap(a, 0, i); // Препострой сортиращото дърво за 33 } // неотсортираната част от масива 34 } 35 */ 36 37 .global heapSort !void heapSort(int *a, int n) //r0 (g23), r1 38 heapSort: !{ int i, tmp; //g20 (g24),g20 39 { setwd wsz=8,nfx=1 40 shrd %r1,1,%g20 ! for (i = n / 2; i >= 0; i--) 41 subd %r1,1,%g24 !n-- 42 0000 2480001C F4C1811B F8C18113 F7C08005 00000000 10010000 ord %r0,0,%g23 } !a 43 L1: { ord %g20,0,%g19 !i 44 0018 12400004 F3C0F405 14000040 00000000 disp %ctpr1,DownHeap } 45 { call %ctpr1,wbs=4 ! downHeap(a, i, n);//g23,g19,g24 46 0028 13900004 200400C0 F4C1F413 04000050 subd %g20,1,%g20 } ! // i--) 47 { cmpledb 0,%g20,%pred0 ! // i >= 0; 48 0038 12400004 E0F4C021 FCFFFF4F 00000000 disp %ctpr1,L1 } 49 0048 01100000 400400C0 ct %ctpr1 ? %pred0 50 L2: { ldd [%g23],%g17 !a[0] for (i = n - 1; i > 0; i--) { //g24 = i 51 0050 1200200C F1C0F767 F0C3F819 0000F70A shl_addd %g24,3,%g23,%g16}!a + 8*i 52 0060 01000004 F4C0F067 ldd [%g16],%g20 ! tmp = a[i]; 53 { std %g17,[%g16] ! a[i] = a[0]; 54 std %g20,[%g23] ! a[0] = tmp; 55 xord %g19,%g19,%g19 !k = 0 56 subd %g24,1,%g24 !i-- (n--) 57 0068 2540009C F3F3F309 F8C1F813 F1C0F027 F4C0F727 0A000040 disp %ctpr1,DownHeap } 58 0080 12900000 200400C0 04000050 00000000 call %ctpr1,wbs=4 ! downHeap(a, 0, i);//g23,g19,g24 59 { cmpedb %g24,0,%pred0 ! } // i > 0 60 0090 12400004 40C0F821 F8FFFF4F 00000000 disp %ctpr1,L2 } 61 00a0 01100000 600400C0 ct %ctpr1 ? ~%pred0!} 62 00a8 01400000 000000F0 return %ctpr3 63 00b0 01100000 200C00C0 ct %ctpr3 !void downHeap(int *a,int k,int n)//g23,g19,g24 64 00b8 11002008 F0C3F319 0000F70A 00000000 DownHeap:shl_addd %g19,3,%g23,%g16!a+8*k{ 65 00c8 01000004 F2C0F067 ldd [%g16],%g18 !tmp=a[k] int i,tmp;/*g17,18*/n--;//вече намалено 66 00d0 01000004 F0C1F81B L3: shrd %g24,1,%g16 !n / 2 for (tmp = a[k]; k <= n / 2; k = i) { 67 { cmpbedb %g19,%g16,%pred0!k <= n / 2? 68 00d8 12400004 60F0F321 15000040 00000000 disp %ctpr1,L4 } 69 { ct %ctpr1 ? ~%pred0 70 00e8 12100004 600400C0 F1C1F319 00000000 shld %g19,1,%g17 } ! i = 2 * k; 71 { shl_addd %g17,3,%g23,%g16!a+8*i 72 00f8 1200200C 20F8F121 F0C3F119 0000F70A cmpbdb %g17,%g24,%pred0 }! if (i < n 73 { ldd [%g16],%g21 ? %pred0 !a[i] && 74 0108 12000114 F5C0F067 F6C8F067 00006014 ldd [%g16+8],%g22 ? %pred0 }!a[i+1] 75 0118 11010104 C0F6F521 00000000 00006004 cmpldb %g21,%g22,%pred0 ? %pred0! a[i] < a[i+1]) 76 0128 11000104 F1C1F111 00000000 00006004 addd %g17,1,%g17 ? %pred0! i++; 77 0138 11002008 F0C3F119 0000F70A 00000000 shl_addd %g17,3,%g23,%g16!a+8*i 78 0148 01000004 F5C0F067 ldd [%g16],%g21 !a[i] if (tmp >= a[i]) 79 { cmpledb %g21,%g18,%pred0! break; 80 0150 1200200C E0F2F521 F0C3F319 0000F70A shl_addd %g19,3,%g23,%g16 }!a+8*k 81 { std %g21,[%g16] ? ~%pred0! a[k] = a[i]; 82 ord %g17,0,%g19 ? ~%pred0! } // k = i 83 0160 23400114 F3C0F105 F5C0F027 EEFFFF4F 00000000 0000E016 disp %ctpr1,L3 } 84 0178 01100000 600400C0 ct %ctpr1 ? ~%pred0 85 0180 11002008 F0C3F319 0000F70A 00000000 L4: shl_addd %g19,3,%g23,%g16!a+8*k 86 { std %g18,[%g16] ! a[k] = tmp; 87 0190 12400010 F2C0F027 000000F0 00000000 return %ctpr3 } 88 01a0 01100000 200C00C0 ct %ctpr3 !} S/390x LISTING getvlq.s page 1 1 #unsigned getVLQ(unsigned char **src) 2 #{ // прочети величина с променлива дължина 3 # unsigned char c, *p = *src;// (вж. Standard MIDI-File Format Spec. 1.1) 4 # unsigned value = *p++; 5 # if (value & 0x80) { 6 # value &= 0x7f; 7 # do 8 # value = (value << 7) + ((c = *p++) & 0x7f); 9 # while (c & 0x80); 10 # } 11 # *src = p; 12 # return value; 13 #} 14 15 .global getvlq 16 getvlq: # src = рег. 2, c = рег. 1, p = рег. 3 17 0000 B9820044 XGR 4,4 # value се съставя в рег. 4 18 0004 B9820011 XGR 1,1 # старшите байтове трябва да бъдат 0 в началото 19 0008 E3302000 0004 LG 3,0(2) # получи указателя към потока от данни 20 000e A7F40009 J L2 # премини към получаване на първия байт 21 0012 A517007F L1: NILL 1,0x7F # маскирай бит 7, остави значещите битове 0-6 22 0016 1641 OR 4,1 # „сглоби“ най-младшия засега байт 23 0018 89400007 SLL 4,7 # value <<= 7 24 001c A73B0001 AGHI 3,1 # обнови адреса 25 0020 BF113000 L2: ICM 1,1,0(3) # получи следващия байт 26 0024 A744FFF7 JM L1 # ако има ли още байтове (бит 7 = 1), продължи 27 0028 A73B0001 AGHI 3,1 # укажи към следващите данни 28 002c E3302000 0024 STG 3,0(2) # съхрани указателя 29 0032 B9E61024 OGRK 2,4,1 # „сглоби“ стойността и я върни в рег. 2 30 0036 07FE BR 14 AMD64 GAS getvlq.s page 1 1 #unsigned getVLQ(unsigned char **src) 2 #{ // прочети величина с променлива дължина 3 # unsigned char c, *p = *src;// (вж. Standard MIDI-File Format Spec. 1.1) 4 # unsigned value = *p++; 5 # if (value & 0x80) { 6 # value &= 0x7f; 7 # do 8 # value = (value << 7) + ((c = *p++) & 0x7f); 9 # while (c & 0x80); 10 # } 11 # *src = p; 12 # return value; 13 #} 14 15 .intel_syntax noprefix 16 .global getvlq 17 getvlq: # src = RDI, p = RSI 18 0000 31C0 XOR EAX,EAX # value = EAX c = AL 19 0002 488B37 MOV RSI,[RDI] # получи адреса 20 0005 AC L1: LODSB # прочети следващия байт и обнови адреса 21 0006 C1C808 ROR EAX,8 # намести байта като най старши; има ли други? 22 0009 72FA JC L1 # да, продължи 23 000b 0FC8 BSWAP EAX # не, постави байтовете на местата им 24 000d BA7F7F7F 7F MOV EDX,0x7F7F7F7F # подготви маска за сгъстяване на битовете 25 0012 C4E27AF5 C2 PEXT EAX,EAX,EDX # остави само значещите 26 0017 488937 MOV [RDI],RSI # съхрани новия адрес 27 001a C3 RET AARCH64 GAS getvlq.s page 1 1 /* 2 unsigned getVLQ(unsigned char **src) 3 { // прочети величина с променлива дължина 4 unsigned char c, *p = *src; // (вж. Standard MIDI-File Format Spec. 1.1) 5 unsigned value = *p++; 6 if (value & 0x80) { 7 value &= 0x7f; 8 do 9 value = (value << 7) + ((c = *p++) & 0x7f); 10 while (c & 0x80); 11 } 12 *src = p; 13 return value; 14 } 15 */ 16 17 .global getvlq 18 getvlq: 19 0000 030040F9 LDR X3,[X0] // src = X0, c = W1, p = X3 20 0004 E2031F2A MOV W2,WZR // value ще се натрупва в W2 21 0008 61144038 L1: LDRB W1,[X3],#1 // получи следващия байт и обнови адреса 22 000c 3F000271 CMP W1,#0x80 // има ли още байтове? 23 0010 21180012 AND W1,W1,#0x7F //(маскирай бит 7, остави значещите битове 0-6 24 0014 221C022A ORR W2,W1,W2,LSL #7 //value <<= 7, „сглоби“ най-младшия дотук байт) 25 0018 82FFFF54 BHS L1 // да, продължи 26 001c 030000F9 STR X3,[X0] // не, съхрани указателя към следващите данни 27 0020 E003022A MOV W0,W2 // върни стойността в X0 28 0024 C0035FD6 RET ARC GAS getvlq.s page 1 1 /* 2 unsigned getVLQ(unsigned char **src) 3 { // прочети величина с променлива дължина 4 unsigned char c, *p = *src; // (вж. Standard MIDI-File Format Spec. 1.1) 5 unsigned value = *p++; 6 if (value & 0x80) { 7 value &= 0x7f; 8 do 9 value = (value << 7) + ((c = *p++) & 0x7f); 10 while (c & 0x80); 11 } 12 *src = p; 13 return value; 14 } 15 */ 16 17 .global getvlq 18 getvlq: 19 0000 0010 4308 LDL r3,[r0] # src = r0, c = r1, p = r3 20 0004 00DA MOVL_S r2,0 # value ще се натрупва в r2 21 0006 0113 8104 L1: LDB.AB r1,[r3,1] # получи следващия байт и обнови адреса 22 000a 605A C201 ASLL r2,r2,7 # value <<= 7 23 000e 5359 8C01 BMSKL r12,r1,6 # маскирай бит 7, остави значещите битове 0-6 24 0012 977A ORL_S r2,r2,r12 # „сглоби“ най-младшия дотук байт 25 0014 F309 DF81 BBIT1L r1,7,L1 # ако не е последен байт, премини към следващия 26 0018 0018 C700 STL r3,[r0] # не, съхрани указателя към следващите данни 27 001c 4440 MOVL_S r0,r2 # върни стойността в r0 28 001e E07E J_S [blink] PPC LISTING getvlq.s page 1 1 #unsigned getVLQ(unsigned char **src) 2 #{ // прочети величина с променлива дължина 3 # unsigned char c, *p = *src;// (вж. Standard MIDI-File Format Spec. 1.1) 4 # unsigned value = *p++; 5 # if (value & 0x80) { 6 # value &= 0x7f; 7 # do 8 # value = (value << 7) + ((c = *p++) & 0x7f); 9 # while (c & 0x80); 10 # } 11 # *src = p; 12 # return value; 13 #} 14 15 .global getvlq 16 getvlq: 17 0000 E8C30000 ld r6,0(r3) # src = r3, c = r4, p = r6 18 0004 38A00000 li r5,0 # value ще се натрупва в r5 19 0008 38C6FFFF addi r6,r6,-1 # компенсирай преинкрементната адресация 20 000c 8C860001 L1: lbzu r4,1(r6) # получи следващия байт и обнови адреса 21 0010 28240080 cmpldi r4,0x80 # има ли още байтове? 22 0014 78A53E24 sldi r5,r5,7 # (value <<= 7, 23 0018 7885066C rldimi r5,r4,0,57 # „сглоби“ най-младшия дотук байт) 24 001c 4080FFF0 bge L1 # да, продължи 25 0020 38C60001 addi r6,r6,1 # не, укажи към следващия байт 26 0024 F8C30000 std r6,0(r3) # съхрани указателя към следващите данни 27 0028 7CA32B78 mr r3,r5 # върни стойността в r3 28 002c 4E800020 blr SPARC GAS getvlq.s page 1 1 /* 2 unsigned getVLQ(unsigned char **src) 3 { // прочети величина с променлива дължина 4 unsigned char c, *p = *src; // (вж. Standard MIDI-File Format Spec. 1.1) 5 unsigned value = *p++; 6 if (value & 0x80) { 7 value &= 0x7f; 8 do 9 value = (value << 7) + ((c = *p++) & 0x7f); 10 while (c & 0x80); 11 } 12 *src = p; 13 return value; 14 } 15 */ 16 17 .global getvlq 18 getvlq: 19 0000 D45A0000 ldx [%o0],%o2 ! src = %o0, c = %o1, p = %o2 20 0004 96100000 clr %o3 ! value ще се натрупва в %o3 21 0008 D20A8000 L1: ldub [%o2],%o1 ! получи следващия байт 22 000c 80A26080 cmp %o1,0x80 ! има ли още байтове? 23 0010 920A607F and %o1,0x7F,%o1 ! (маскирай бит 7, остави значещите битове 0-6 24 0014 972AF007 sllx %o3,7,%o3 ! value <<= 7, 25 0018 9612C009 or %o3,%o1,%o3 ! „сглоби“ най-младшия дотук байт) 26 001c 1A6FFFFB bcc %xcc,L1 ! да, продължи (изпълнява се след „inc“!) 27 0020 9402A001 inc %o2 ! обнови адреса 28 0024 D4720000 stx %o2,[%o0] ! не, съхрани указателя към следващите данни 29 0028 81C3E008 retl ! изпълнява се след „mov“! 30 002c 9010000B mov %o3,%o0 ! върни стойността в %o0 MIPS LISTING getvlq.s page 1 1 #unsigned getVLQ(unsigned char **src) 2 #{ // прочети величина с променлива дължина 3 # unsigned char c, *p = *src;// (вж. Standard MIDI-File Format Spec. 1.1) 4 # unsigned value = *p++; 5 # if (value & 0x80) { 6 # value &= 0x7f; 7 # do 8 # value = (value << 7) + ((c = *p++) & 0x7f); 9 # while (c & 0x80); 10 # } 11 # *src = p; 12 # return value; 13 #} 14 15 .ent getvlq 16 .global getvlq 17 getvlq: 18 0000 DC860000 LD $6,0($4) # src = $4, c = $5, p = $6 19 0004 24020000 LI $2,0 # value ще се натрупва в $2 20 0008 80C50000 L1: LB $5,0($6) # получи следващия байт и разшири знака 21 000c 64C60001 DADDIU $6,$6,1 # обнови адреса 22 0010 000211F8 DSLL $2,$2,7 # value <<= 7 23 DINS $2,$5,0,7 # „сглоби“ най-младшия дотук байт 24 0014 04A0FFFC 7CA23007 BLTZ $5,L1 # ако има още байтове, премини към следващия 25 SD $6,0($4) # съхрани указателя към следващите данни 26 001c 03E00008 FC860000 JR $31 # върни стойността в $2 27 0024 00000000 00000000 00000000 .end getvlq RISC-V LISTING getvlq.s page 1 1 #unsigned getVLQ(unsigned char **src) 2 #{ // прочети величина с променлива дължина 3 # unsigned char c, *p = *src;// (вж. Standard MIDI-File Format Spec. 1.1) 4 # unsigned value = *p++; 5 # if (value & 0x80) { 6 # value &= 0x7f; 7 # do 8 # value = (value << 7) + ((c = *p++) & 0x7f); 9 # while (c & 0x80); 10 # } 11 # *src = p; 12 # return value; 13 #} 14 15 .global getvlq 16 getvlq: 17 0000 03360500 LD a2,0(a0) # src = a0, c = a1, p = a2 18 0004 93060000 LI a3,0 # value ще се натрупва в a3 19 0008 83050600 L1: LB a1,0(a2) # получи следващия байт и разшири знака 20 000c 13061600 ADDI a2,a2,1 # обнови адреса 21 0010 13F7F507 ANDI a4,a1,0x7F # маскирай бит 7, остави значещите битове 0-6 22 0014 93967600 SLLI a3,a3,7 # value <<= 7 23 0018 B3E6E600 OR a3,a3,a4 # „сглоби“ най-младшия дотук байт 24 001c E3C605FE BLTZ a1,L1 # ако има още байтове, премини към следващия 25 0020 2330C500 SD a2,0(a0) # съхрани указателя към следващите данни 26 0024 13850600 MV a0,a3 # върни стойността в a0 27 0028 67800000 RET LOONGARCH64 GAS getvlq.s page 1 1 #unsigned getVLQ(unsigned char **src) 2 #{ // прочети величина с променлива дължина 3 # unsigned char c, *p = *src;// (вж. Standard MIDI-File Format Spec. 1.1) 4 # unsigned value = *p++; 5 # if (value & 0x80) { 6 # value &= 0x7f; 7 # do 8 # value = (value << 7) + ((c = *p++) & 0x7f); 9 # while (c & 0x80); 10 # } 11 # *src = p; 12 # return value; 13 #} 14 15 .global getvlq 16 getvlq: 17 0000 8600C028 LD.D $r6,$r4,0 # src = r4, c = r5, p = r6 18 0004 07001500 OR $r7,$r0,$r0 # value ще се натрупва в r7 19 0008 C5000028 L1: LD.B $r5,$r6,0 # получи следващия байт и разшири знака 20 000c C604C002 ADDI.D $r6,$r6,1 # обнови адреса 21 0010 E71C4100 SLLI.D $r7,$r7,7 # value <<= 7 22 0014 A7008600 BSTRINS.D $r7,$r5,6,0 # „сглоби“ най-младшия дотук байт 23 0018 A0F0FF63 BLTZ $r5,L1 # ако има още байтове, премини към следващия 24 001c 8600C029 ST.D $r6,$r4,0 # съхрани указателя към следващите данни 25 0020 E4001500 OR $r4,$r7,$r0 # върни стойността в r4 26 0024 2000004C JIRL $r0,$r1,0 #unsigned getVLQ(unsigned char **src) #{ // прочети величина с променлива дължина # unsigned char c, *p = *src;// (вж. Standard MIDI-File Format Spec. 1.1) # unsigned value = *p++; # if (value & 0x80) { # value &= 0x7f; # do # value = (value << 7) + ((c = *p++) & 0x7f); # while (c & 0x80); # } # *src = p; # return value; getvlq.o: file format ecoff-littlealpha #} Disassembly of section .text: .ent getvlq .globl getvlq 0000000000000000 : getvlq: 0: 00 00 30 a4 ldq t0,0(a0) ldq $1,0($16) # src = $16, c = $2, p = $1 4: 00 04 ff 47 clr v0 bis $31,$31,$0 # value ще се натрупва в $0 8: 00 00 41 28 ldbu t1,0(t0) L1: ldbu $2,0($1) # получи следващия байт (няма „ldbs“) c: 02 00 e2 73 sextb t1,t1 sextb $2,$2 # разшири знака 10: 20 f7 00 48 sll v0,0x7,v0 addq $1,1,$1 # обнови адреса 14: 03 f0 4f 44 and t1,0x7f,t2 sll $0,7,$0 # value <<= 7 18: 01 34 20 40 addq t0,0x1,t0 and $2,0x7F,$3 # маскирай бит 7, остави значещите битове 0-6 1c: 00 04 03 44 or v0,t2,v0 bis $0,$3,$0 # „сглоби“ най-младшия дотук байт 20: f9 ff 5f e8 blt t1,8 blt $2,L1 # ако има още байтове, премини към следващия 24: 00 00 30 b4 stq t0,0(a0) stq $1,0($16) # съхрани указателя към следващите данни 28: 01 80 fa 6b ret zero,(ra),0x1 ret # върни стойността в $0 2c: 1f 04 ff 47 nop .end getvlq GAS for MMIX getvlq.s page 1 1 %unsigned getVLQ(unsigned char **src) 2 %{ // прочети величина с променлива дължина 3 % unsigned char c, *p = *src;// (вж. Standard MIDI-File Format Spec. 1.1) 4 % unsigned value = *p++; 5 % if (value & 0x80) { 6 % value &= 0x7f; 7 % do 8 % value = (value << 7) + ((c = *p++) & 0x7f); 9 % while (c & 0x80); 10 % } 11 % *src = p; 12 % return value; 13 %} 14 15 .global getvlq 16 getvlq: 17 0000 8D010000 LDO $1,$0,0 % p = $1, c = $2 18 0004 C1030000 OR $3,$0,0 % src = $3 19 0008 C6000000 XOR $0,$0,$0 % value ще се натрупва в $0 20 000c 81020100 L1: LDB $2,$1,0 % получи следващия байт и разшири знака 21 0010 23010101 ADDU $1,$1,1 % обнови адреса 22 0014 3B000007 SLU $0,$0,7 % value <<= 7 23 0018 C904027F AND $4,$2,0x7F % маскирай бит 7, остави значещите битове 0-6 24 001c C0000004 OR $0,$0,$4 % „сглоби“ най-младшия дотук байт 25 0020 4102FFFB BN $2,L1 % ако има още байтове, премини към следващия 26 0024 AD010300 STO $1,$3,0 % съхрани указателя към следващите данни 27 0028 F8010000 POP 1,0 % върни стойността в $0 HPPA64 LISTING getvlq.s page 1 1 /* 2 unsigned getVLQ(unsigned char **src) 3 { // прочети величина с променлива дължина 4 unsigned char c, *p = *src; // (вж. Standard MIDI-File Format Spec. 1.1) 5 unsigned value = *p++; 6 if (value & 0x80) { 7 value &= 0x7f; 8 do 9 value = (value << 7) + ((c = *p++) & 0x7f); 10 while (c & 0x80); 11 } 12 *src = p; 13 return value; 14 } 15 */ 16 .global getvlq 17 getvlq: 18 0000 0F4010D8 LDD 0(%R26),%R24 ; %R26 = src, %R25 = c, %R24 = p 19 0004 341C0000 LDI 0,%R28 ; value ще се натрупва в %R28 20 0008 0F021039 L1: LDB,MA 1(%R24),%R25 ; Получи следващия байт и обнови адреса 21 000c D39C08DC SHRPW %R28,%R28,25,%R28; value <<= 7 22 0010 C7195FE5 BB,< %R25,24,L1 ; Има още байтове? (Изпълнява се след „DEP“!) 23 0014 D7990C19 DEPW %R25,31,7,%R28 ; Замени битове 6-0 със съответните битове на c 24 0018 0F5812C0 STD %R24,0(%R26) ; Съхрани указателя към следващите данни 25 001c E840D002 BVE,N (%R2) TILE-Gx GAS getvlq.s page 1 1 #unsigned getVLQ(unsigned char **src) 2 #{ // прочети величина с променлива дължина 3 # unsigned char c, *p = *src;// (вж. Standard MIDI-File Format Spec. 1.1) 4 # unsigned value = *p++; 5 # if (value & 0x80) { 6 # value &= 0x7f; 7 # do 8 # value = (value << 7) + ((c = *p++) & 0x7f); 9 # while (c & 0x80); 10 # } 11 # *src = p; 12 # return value; 13 #} 14 15 .global getvlq 16 getvlq: 17 { LD r2,r0 # src = r0, c = r1, p = r2 18 0000 C3FF0B54 0040169E MOVE r3,zero } # value ще се натрупва в r3 19 L1: { LD1S_ADD r1,r2,1 # получи 1 байт, разшири знака и обнови адреса 20 0008 C37008E0 40083818 SHLI r3,r3,7 } # value <<= 7 21 { BFINS r3,r1,0,6 # „сглоби“ най-младшия дотук байт 22 0010 436000B6 3FF87F17 BLTZ r1,L1 } # ако има още байтове, премини към следващия 23 { ST r0,r2 # съхрани указателя към следващите данни 24 MOVE r0,r3 # върни стойността в r0 25 0018 C0F00B54 E06E16DE JR lr } IA-64 GAS getvlq.s page 1 1 //unsigned getVLQ(unsigned char **src) 2 //{ // прочети величина с променлива дължина 3 // unsigned char c, *p = *src;// (вж. Standard MIDI-File Format Spec. 1.1) 4 // unsigned value = *p++; 5 // if (value & 0x80) { 6 // value &= 0x7f; 7 // do 8 // value = (value << 7) + ((c = *p++) & 0x7f); 9 // while (c & 0x80); 10 // } 11 // *src = p; 12 // return value; 13 //} 14 15 .global getvlq 16 getvlq: 17 ALLOC loc0=ar.pfs,1,3,0,0 18 LD8 loc1=[in0] // src = in0, c = loc2, p = loc1 19 MOV r8=r0 // value ще се натрупва в r8 20 0000 09081108 80052002 80302000 01000084 L1: LD1 loc2=[loc1],1 // получи следващия байт и обнови адреса 21 SXT1 loc2=loc2 // разшири знака 22 SHL r8=r8,7 // value <<= 7 23 0010 0A180544 00140000 00020060 04185100 DEP r8=loc2,r8,0,7 // „сглоби“ най-младшия дотук байт 24 CMP.LT p6,p7=loc2,r0 // има ли още байтове? 25 0020 02000000 01008040 E0F02900 3142D84F (p6) BR L1 // да, премини към следващия 26 ST8 [in0]=loc1 // не, съхрани указателя към следващите данни 27 0030 10308C00 07300000 00020003 E0FFFF48 BR.RET.SPTK rp // и върни стойността в r8 27 11008840 98110000 00020080 00008400 E2K GAS getvlq.s page 1 1 !unsigned getVLQ(unsigned char **src) 2 !{ // прочети величина с променлива дължина 3 ! unsigned char c, *p = *src;// (вж. Standard MIDI-File Format Spec. 1.1) 4 ! unsigned value = *p++; 5 ! if (value & 0x80) { 6 ! value &= 0x7f; 7 ! do 8 ! value = (value << 7) + ((c = *p++) & 0x7f); 9 ! while (c & 0x80); 10 ! } 11 ! *src = p; 12 ! return value; 13 !} 14 15 .global getvlq 16 getvlq: 17 { ldd [%r0],%r1 ! src = r0, c = r2, p = r1 18 xord %r3,%r3,%r3 ! value ще се натрупва в r3 19 0000 1340000C 81C08067 83838309 03000040 disp %ctpr1,L1 } ! подготви прехода в началото на цикъла 20 0010 01400000 000000F0 return %ctpr3 ! и връщането към извикващата функция 21 L1: { ldb [%r1],%r2 ! получи следващия байт 22 0018 1200000C 82C08164 81C18111 00000000 addd %r1,1,%r1 } ! обнови адреса 23 { insfd %r3,7 << 6 | 57,%r2,%r3!value<<=7,сглоби най-младшия дотук байт 24 0028 2200100C 83D4836D 20D08221 0000820B 00000000 8000F901 cmpbdb %r2,0x80,%pred0 }!има ли още байтове? 25 0040 01100000 600400C0 ct %ctpr1 ? ~%pred0! да, премини към следващия 26 { std %r1,[%r0] ! не, съхрани указателя към следващите данни 27 ord %r3,0,%r0 ! и върни стойността в r0 28 0048 13100014 200C00C0 80C08305 81C08027 ct %ctpr3 } S/390x LISTING putvlq.s page 1 1 #unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 2 #{ // (вж. Standard MIDI-File Format Spec. 1.1) 3 # unsigned buffer = value & 0x7f; 4 # while ((value >>= 7) > 0) { 5 # buffer <<= 8; 6 # buffer |= 0x80; 7 # buffer += value & 0x7f; 8 # } 9 # for ( ; ; ) { 10 # *dest++ = (unsigned char)buffer; 11 # if (buffer & 0x80) 12 # buffer >>= 8; 13 # else 14 # return dest; 15 # } 16 #} 17 18 .global putvlq 19 putvlq: #//value се предава в рег. 2, dest - в рег. 3 20 0000 1842 LR 4,2 # buffer = value 21 0002 C04B0000 007F NILF 4,0x7F # & 0x7f; 22 0008 8A200007 L1: SRA 2,7 # while ((value >>= 7) > 0)//value e 28 бита 23 000c A784000D JZ L2 # { 24 0010 89400008 SLL 4,8 # buffer <<= 8; 25 0014 A54B0080 OILL 4,0x80 # buffer |= 0x80; 26 0018 1852 LR 5,2 # value 27 001a C05B0000 007F NILF 5,0x7F # & 0x7f; 28 0020 1E45 ALR 4,5 # buffer += 29 0022 A7F4FFF3 J L1 # } for ( ; ; ) { 30 0026 42403000 L2: STC 4,0(3) # *dest = (unsigned char)buffer; 31 002a A73B0001 AGHI 3,1 # ++ 32 002e A7410080 TMLL 4,0x80 # if (buffer & 0x80) 33 0032 A7840006 JZ L3 # { 34 0036 88400008 SRL 4,8 # buffer >>= 8; 35 003a A7F4FFF6 J L2 # } 36 003e B9040023 L3: LGR 2,3 # else return dest; 37 0042 07FE BR 14 # } AMD64 GAS putvlq.s page 1 1 #unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 2 #{ // (вж. Standard MIDI-File Format Spec. 1.1) 3 # unsigned buffer = value & 0x7f; 4 # while ((value >>= 7) > 0) { 5 # buffer <<= 8; 6 # buffer |= 0x80; 7 # buffer += value & 0x7f; 8 # } 9 # for ( ; ; ) { 10 # *dest++ = (unsigned char)buffer; 11 # if (buffer & 0x80) 12 # buffer >>= 8; 13 # else 14 # return dest; 15 # } 16 #} 17 18 .intel_syntax noprefix 19 .global putvlq 20 putvlq: # "value" се предава в RDI, "dest" - в RSI 21 0000 4887FE XCHG RSI,RDI # "value" = RSI, заради STOSB "dest" ще е в RDI 22 0003 B87F7F7F 7F MOV EAX,0x7F7F7F7F # подготви маска за буфера (в EAX заради STOSB) 23 0008 C4E24BF5 C0 PDEP EAX,ESI,EAX # разтегни в буфера значещите битове на "value" 24 000d F30FBDC8 LZCNT ECX,EAX # CL = 32 − брой значещи битове 25 0011 0D008080 80 OR EAX,0x80808000 # установи битовете-маркери за непоследен байт 26 0016 80E118 AND CL,0x18 # измести буфера на кратен на 8 брой битове 27 0019 D3E0 SHL EAX,CL # (ако "value" = 0, изместване няма да има) 28 001b 0FC8 BSWAP EAX # записът започва от най-старшия байт 29 001d AA L1: STOSB #for(;;){*dest++ = (unsigned char)buffer; 30 001e C1E808 SHR EAX,8 #___ ___ if (buffer & 0x80) 31 0021 72FA JC L1 #___X___ buffer >>= 8; 32 0023 4897 XCHG RAX,RDI # else return dest; 33 0025 C3 RET # } AARCH64 GAS putvlq.s page 1 1 /* 2 unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 3 { // (вж. Standard MIDI-File Format Spec. 1.1) 4 unsigned buffer = value & 0x7f; 5 while ((value >>= 7) > 0) { 6 buffer <<= 8; 7 buffer |= 0x80; 8 buffer += value & 0x7f; 9 } 10 for ( ; ; ) { 11 *dest++ = (unsigned char)buffer; 12 if (buffer & 0x80) 13 buffer >>= 8; 14 else 15 return dest; 16 } 17 } 18 */ 19 20 .global putvlq // Регистри: value = W0, dest = X1, buffer = W2 21 putvlq: //putVLQ(unsigned value, unsigned char *dest) { 22 0000 02180012 AND W2,W0,#0x7F // unsigned buffer = value & 0x7f; 23 0004 007C0753 L1: LSR W0,W0,#7 // while ((value >>= 7) > 0) { 24 0008 A0000034 CBZ W0,L2 25 000c 425C1853 LSL W2,W2,#8 // buffer <<= 8; 26 0010 42001932 ORR W2,W2,#0x80 // buffer |= 0x80; 27 0014 02180033 BFI W2,W0,#0,#7 // buffer += value & 0x7f; 28 0018 FBFFFF17 B L1 // } for ( ; ; ) { 29 001c 22140038 L2: STRB W2,[X1],#1 // *dest++ = (unsigned char)buffer; 30 0020 42208213 ROR W2,W2,#8 // if (buffer & 0x80) buffer >>= 8; 31 0024 C2FFFF37 TBNZ W2,#31,L2 // else return dest; 32 0028 E00301AA MOV X0,X1 // } 33 002c C0035FD6 RET //} ARC GAS putvlq.s page 1 1 /* 2 unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 3 { // (вж. Standard MIDI-File Format Spec. 1.1) 4 unsigned buffer = value & 0x7f; 5 while ((value >>= 7) > 0) { 6 buffer <<= 8; 7 buffer |= 0x80; 8 buffer += value & 0x7f; 9 } 10 for ( ; ; ) { 11 *dest++ = (unsigned char)buffer; 12 if (buffer & 0x80) 13 buffer >>= 8; 14 else 15 return dest; 16 } 17 } 18 */ 19 20 .global putvlq # Регистри: value = r0, dest = r1, buffer = r2 21 putvlq: #putVLQ(unsigned value, unsigned char *dest) { 22 0000 5358 8201 BMSKL r2,r0,6 # unsigned buffer = value & 0x7f; 23 0004 6158 C081 L1: LSRL.F r0,r0,7 # while ((value >>= 7) > 0) { 24 0008 E05A 2202 ASLL.NZ r2,r2,8 # buffer <<= 8; 25 000c CF5A E201 BSETL.NZ r2,r2,7# buffer |= 0x80; 26 0010 5358 8301 BMSKL r3,r0,6 # buffer += value & 0x7f; 27 0014 C05A C200 ADDL.NZ r2,r2,r3# _} 28 0018 F6F5 BNE_S L1 #__/ for ( ; ; ) { 29 001a 0119 9200 L2: STB.AB r2,[r1,1]# *dest++ = (unsigned char)buffer; 30 001e 615A 0282 LSRL.F r2,r2,8 # if (buffer & 0x80) buffer >>= 8; 31 0022 BDF7 BLO_S L2 # else return dest; 32 0024 2440 MOVL_S r0,r1 # } 33 0026 E07E J_S [blink] #} PPC LISTING putvlq.s page 1 1 #unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 2 #{ // (вж. Standard MIDI-File Format Spec. 1.1) 3 # unsigned buffer = value & 0x7f; 4 # while ((value >>= 7) > 0) { 5 # buffer <<= 8; 6 # buffer |= 0x80; 7 # buffer += value & 0x7f; 8 # } 9 # for ( ; ; ) { 10 # *dest++ = (unsigned char)buffer; 11 # if (buffer & 0x80) 12 # buffer >>= 8; 13 # else 14 # return dest; 15 # } 16 #} 17 18 .global putvlq #//Регистри: value = r3, dest = r4, buffer = r5 19 putvlq: #putVLQ(unsigned value, unsigned char *dest) { 20 0000 7065007F andi. r5,r3,0x7F # unsigned buffer = value & 0x7f; 21 0004 7863C9C3 L1: srdi. r3,r3,7 # while ((value >>= 7) > 0) { 22 0008 41820014 beq L2 23 000c 78A545E4 sldi r5,r5,8 # buffer <<= 8; 24 0010 60A50080 ori r5,r5,0x80 # buffer |= 0x80; 25 0014 7865066C rldimi r5,r3,0,57 # buffer += value & 0x7f; 26 0018 4BFFFFEC b L1 # } 27 001c 3884FFFF L2: addi r4,r4,-1#компенс. for ( ; ; ) { 28 0020 9CA40001 L3: stbu r5,1(r4) # *dest++ = (unsigned char)buffer; 29 0024 70A60080 andi. r6,r5,0x80 # if (buffer & 0x80) 30 0028 4182000C beq L4 #__ 31 002c 78A5C202 srdi r5,r5,8 # \ buffer >>= 8; 32 0030 4BFFFFF0 b L3 # \___ else return dest; 33 0034 38640001 L4: addi r3,r4,1 #++ } 34 0038 4E800020 blr #} SPARC GAS putvlq.s page 1 1 /* 2 unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 3 { // (вж. Standard MIDI-File Format Spec. 1.1) 4 unsigned buffer = value & 0x7f; 5 while ((value >>= 7) > 0) { 6 buffer <<= 8; 7 buffer |= 0x80; 8 buffer += value & 0x7f; 9 } 10 for ( ; ; ) { 11 *dest++ = (unsigned char)buffer; 12 if (buffer & 0x80) 13 buffer >>= 8; 14 else 15 return dest; 16 } 17 } 18 */ 19 20 .global putvlq !//Рег.: value = %o0, dest = %o1, buffer = %o2 21 putvlq: !putVLQ(unsigned value, unsigned char *dest) { 22 0000 940A207F and %o0,0x7F,%o2 ! unsigned buffer = value & 0x7f; 23 0004 91323007 L1: srlx %o0,7,%o0 ! while ((value >>= 7) > 0) { 24 0008 02CA0007 brz %o0,L2 25 000c 01000000 nop 26 0010 952AB008 sllx %o2,8,%o2 ! buffer <<= 8; 27 0014 9412A080 or %o2,0x80,%o2 ! buffer |= 0x80; 28 0018 960A207F and %o0,0x7F,%o3 ! buffer += value & 0x7f; 29 001c 10BFFFFA ba L1! изпълнява се след „add“ 30 0020 9402800B add %o2,%o3,%o2 31 0024 D42A4000 L2: stb %o2,[%o1] !___ } for ( ; ; ) { 32 0028 92026001 inc %o1 !++ \___ *dest++ = (unsigned char)buffer; 33 002c 808AA080 andcc %o2,0x80,%g0 !___ 34 0030 02680004 be %xcc,L3 !__ \___ if (buffer & 0x80) 35 0034 01000000 nop ! \ 36 0038 10BFFFFB ba L2! изпълнява се след „srl“ 37 003c 9532B008 srlx %o2,8,%o2 ! \ buffer >>= 8; 38 0040 81C3E008 L3: retl ! \_ else return dest; 39 0044 90100009 mov %o1,%o0! изпълнява се преди „retl“ MIPS LISTING putvlq.s page 1 1 #unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 2 #{ // (вж. Standard MIDI-File Format Spec. 1.1) 3 # unsigned buffer = value & 0x7f; 4 # while ((value >>= 7) > 0) { 5 # buffer <<= 8; 6 # buffer |= 0x80; 7 # buffer += value & 0x7f; 8 # } 9 # for ( ; ; ) { 10 # *dest++ = (unsigned char)buffer; 11 # if (buffer & 0x80) 12 # buffer >>= 8; 13 # else 14 # return dest; 15 # } 16 #} 17 18 .ent putvlq 19 .global putvlq #//Регистри: value = $4, dest = $5, buffer = $6 20 putvlq: #putVLQ(unsigned value, unsigned char *dest) { 21 0000 3086007F ANDI $6,$4,0x7F # unsigned buffer = value & 0x7f; 22 0004 000421FA L1: DSRL $4,$4,7 # while ((value >>= 7) > 0) { 23 0008 10800005 00000000 BEQ $4,$0,L2 24 0010 00063238 DSLL $6,$6,8 # buffer <<= 8; 25 0014 34C60080 ORI $6,$6,0x80 # buffer |= 0x80; 26 DINS $6,$4,0,7 # buffer += value & 0x7f; 27 0018 1000FFFA 7C863007 B L1 # } 28 0020 A0A60000 L2: SB $6,0($5) #___ for ( ; ; ) { 29 0024 64A50001 DADDIU $5,$5,1 #++ \___ *dest++ = (unsigned char)buffer; 30 0028 30C70080 ANDI $7,$6,0x80 # if (buffer & 0x80) 31 002c 10E00003 00000000 BEQ $7,$0,L3 #__ 32 DSRL $6,$6,8 # \ buffer >>= 8; 33 0034 1000FFFA 0006323A B L2 # \___ else return dest; 34 L3: MOVE $2,$5 # } 35 003c 03E00008 00A01025 JR $31 #} //Върни указателя към следващия байт в $2 36 0044 00000000 00000000 00000000 .end putvlq RISC-V LISTING putvlq.s page 1 1 #unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 2 #{ // (вж. Standard MIDI-File Format Spec. 1.1) 3 # unsigned buffer = value & 0x7f; 4 # while ((value >>= 7) > 0) { 5 # buffer <<= 8; 6 # buffer |= 0x80; 7 # buffer += value & 0x7f; 8 # } 9 # for ( ; ; ) { 10 # *dest++ = (unsigned char)buffer; 11 # if (buffer & 0x80) 12 # buffer >>= 8; 13 # else 14 # return dest; 15 # } 16 #} 17 18 .global putvlq #//Регистри: value = a0, dest = a1, buffer = a2 19 putvlq: #putVLQ(unsigned value, unsigned char *dest) { 20 0000 1376F507 ANDI a2,a0,0x7F # unsigned buffer = value & 0x7f; 21 0004 13557500 L1: SRLI a0,a0,7 # while ((value >>= 7) > 0) { 22 0008 630C0500 BEQZ a0,L2 23 000c 13168600 SLLI a2,a2,8 # buffer <<= 8; 24 0010 13660608 ORI a2,a2,0x80 # buffer |= 0x80; 25 0014 9376F507 ANDI a3,a0,0x7F # buffer += value & 0x7f; 26 0018 3306D600 ADD a2,a2,a3 27 001c 6FF09FFE J L1 # } 28 0020 2380C500 L2: SB a2,0(a1) #___ for ( ; ; ) { 29 0024 93851500 ADDI a1,a1,1 #++ \___ *dest++ = (unsigned char)buffer; 30 0028 93760608 ANDI a3,a2,0x80 # if (buffer & 0x80) 31 002c 63860600 BEQZ a3,L3 #__ 32 0030 13568600 SRLI a2,a2,8 # \ buffer >>= 8; 33 0034 6FF0DFFE J L2 # \___ else return dest; 34 0038 13850500 L3: MV a0,a1 # } 35 003c 67800000 RET #} //Върни указателя към следващия байт в a0 LOONGARCH64 GAS putvlq.s page 1 1 #unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 2 #{ // (вж. Standard MIDI-File Format Spec. 1.1) 3 # unsigned buffer = value & 0x7f; 4 # while ((value >>= 7) > 0) { 5 # buffer <<= 8; 6 # buffer |= 0x80; 7 # buffer += value & 0x7f; 8 # } 9 # for ( ; ; ) { 10 # *dest++ = (unsigned char)buffer; 11 # if (buffer & 0x80) 12 # buffer >>= 8; 13 # else 14 # return dest; 15 # } 16 #} 17 18 .global putvlq #//Регистри: value = r4, dest = r5, buffer = r6 19 putvlq: #putVLQ(unsigned value, unsigned char *dest) { 20 0000 86FC4103 ANDI $r6,$r4,0x7F # unsigned buffer = value & 0x7f; 21 0004 841C4500 L1: SRLI.D $r4,$r4,7 # while ((value >>= 7) > 0) { 22 0008 80140040 BEQZ $r4,L2 23 000c C6204100 SLLI.D $r6,$r6,8 # buffer <<= 8; 24 0010 C6008203 ORI $r6,$r6,0x80 # buffer |= 0x80; 25 0014 86008600 BSTRINS.D $r6,$r4,6,0 # buffer += value & 0x7f; 26 0018 FFEFFF53 B L1 # } 27 001c A6000029 L2: ST.B $r6,$r5,0 #___ for ( ; ; ) { 28 0020 A504C002 ADDI.D $r5,$r5,1 #++ \___ *dest++ = (unsigned char)buffer; 29 0024 C7004203 ANDI $r7,$r6,0x80 # if (buffer & 0x80) 30 0028 E00C0040 BEQZ $r7,L3 #__ 31 002c C6204500 SRLI.D $r6,$r6,8 # \ buffer >>= 8; 32 0030 FFEFFF53 B L2 # \___ else return dest; 33 0034 A4001500 L3: OR $r4,$r5,$r0 # } 34 0038 2000004C JIRL $r0,$r1,0 #} //Върни указателя към следващия байт в r4 #unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД #{ // (вж. Standard MIDI-File Format Spec. 1.1) # unsigned buffer = value & 0x7f; # while ((value >>= 7) > 0) { # buffer <<= 8; # buffer |= 0x80; # buffer += value & 0x7f; # } # for ( ; ; ) { # *dest++ = (unsigned char)buffer; # if (buffer & 0x80) # buffer >>= 8; # else # return dest; # } putvlq.o: file format ecoff-littlealpha #} Disassembly of section .text: .ent putvlq .globl putvlq #//Рег.: value = $16, dest = $17, buffer = $1 0000000000000000 : putvlq: #putVLQ(unsigned value, unsigned char *dest) { 0: 01 f0 0f 46 and a0,0x7f,t0 and $16,0x7F,$1 # unsigned buffer = value & 0x7f; 4: 90 f6 00 4a srl a0,0x7,a0 L1: srl $16,7,$16 # while ((value >>= 7) > 0) { 8: 05 00 00 e6 beq a0,20 beq $16,L2 c: 21 17 21 48 sll t0,0x8,t0 sll $1,8,$1 # buffer <<= 8; 10: 02 f0 0f 46 and a0,0x7f,t1 bis $1,0x80,$1 # buffer |= 0x80; 14: 01 14 30 44 or t0,0x80,t0 and $16,0x7F,$2 # buffer += value & 0x7f; 18: 01 04 22 40 addq t0,t1,t0 addq $1,$2,$1 1c: f9 ff ff c3 br 4 br $31,L1 # } 20: 00 00 31 38 stb t0,0(a1) L2: stb $1,0($17) #__ for ( ; ; ) { 24: 02 10 30 44 and t0,0x80,t1 addq $17,1,$17 #++\__ *dest++ = (unsigned char)buffer; 28: 11 34 20 42 addq a1,0x1,a1 and $1,0x80,$2 # if (buffer & 0x80) 2c: 02 00 40 e4 beq t1,38 beq $2,L3 #__ 30: 81 16 21 48 srl t0,0x8,t0 srl $1,8,$1 # \ buffer >>= 8; 34: fa ff ff c3 br 20 br $31,L2 # \_ else return dest; 38: 00 04 f1 47 mov a1,v0 L3: bis $31,$17,$0 # } 3c: 01 80 fa 6b ret zero,(ra),0x1 ret #} //Върни указателя към следващия байт в $0 .end putvlq GAS for MMIX putvlq.s page 1 1 %unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 2 %{ // (вж. Standard MIDI-File Format Spec. 1.1) 3 % unsigned buffer = value & 0x7f; 4 % while ((value >>= 7) > 0) { 5 % buffer <<= 8; 6 % buffer |= 0x80; 7 % buffer += value & 0x7f; 8 % } 9 % for ( ; ; ) { 10 % *dest++ = (unsigned char)buffer; 11 % if (buffer & 0x80) 12 % buffer >>= 8; 13 % else 14 % return dest; 15 % } 16 %} 17 18 .global putvlq %//Рег.: value = $0, dest = $1, buffer = $2 19 putvlq: %putVLQ(unsigned value, unsigned char *dest) { 20 0000 C902007F AND $2,$0,0x7F % unsigned buffer = value & 0x7f; 21 0004 3F000007 L1: SRU $0,$0,7 % while ((value >>= 7) > 0) { 22 0008 42000006 BZ $0,L2 23 000c 3B020208 SLU $2,$2,8 % buffer <<= 8; 24 0010 C1020280 OR $2,$2,0x80 % buffer |= 0x80; 25 0014 C903007F AND $3,$0,0x7F % buffer += value & 0x7f; 26 0018 22020203 ADDU $2,$2,$3 27 001c F1FFFFFA JMP L1 % } 28 0020 A3020100 L2: STBU $2,$1,0 %__ for ( ; ; ) { 29 0024 23010101 ADDU $1,$1,1 %++\__ *dest++ = (unsigned char)buffer; 30 0028 C9030280 AND $3,$2,0x80 % if (buffer & 0x80) 31 002c 42030003 BZ $3,L3 %__ 32 0030 3F020208 SRU $2,$2,8 % \ buffer >>= 8; 33 0034 F1FFFFFB JMP L2 % \_ else return dest; 34 0038 C1000100 L3: OR $0,$1,0 % } 35 003c F8010000 POP 1,0 %} //Върни указателя към следващия байт в $0 HPPA64 LISTING putvlq.s page 1 1 ;unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 2 ;{ // (вж. Standard MIDI-File Format Spec. 1.1) 3 ; unsigned buffer = value & 0x7f; 4 ; while ((value >>= 7) > 0) { 5 ; buffer <<= 8; 6 ; buffer |= 0x80; 7 ; buffer += value & 0x7f; 8 ; } 9 ; for ( ; ; ) { 10 ; *dest++ = (unsigned char)buffer; 11 ; if (buffer & 0x80) 12 ; buffer >>= 8; 13 ; else 14 ; return dest; 15 ; } 16 ;} 17 .global putvlq ;%R26 = value, %R25 = dest, %R24 = buffer 18 putvlq: ;putVLQ(unsigned value, unsigned char *dest) { 19 0000 D3581BF9 EXTRW,U %R26,31,7,%R24 ; unsigned buffer = value & 0x7f; 20 0004 D340AB1A L1: SHRPW,<> %R0,%R26,7,%R26; while ((value >>= 7) > 0) { 21 0008 E800001A B,N L2;анул.се при >0 22 000c D31808F8 SHRPW %R24,%R24,24,%R24; buffer <<= 8; 23 0010 D7021CFF DEPWI 1,24,1,%R24 ; buffer |= 0x80; 24 0014 E81F1FD5 B L1 ;изп.се след DEPW____ buffer += value & 0x7f; } 25 0018 D71A0C19 DEPW %R26,31,7,%R24 ;__/ for ( ; ; ) { 26 001c C718C010 L2: BB,>= %R24,24,L3 ;__ ____ *dest++ = (unsigned char)buffer; 27 0020 0F381222 STB,MA %R24,1(%R25) ;__X____ if (buffer & 0x80) 28 0024 E81F1FE5 B L2;изп.се след SHRPW\ __ buffer >>= 8; 29 0028 D3000AF8 SHRPW %R0,%R24,8,%R24 ;____X__ else return dest; 30 002c 0819025C L3: COPY %R25,%R28 ; } 31 0030 E840D002 BVE,N (%R2) ;} //Върни указателя към следващия байт в %R28 TILE-Gx GAS putvlq.s page 1 1 #unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 2 #{ // (вж. Standard MIDI-File Format Spec. 1.1) 3 # unsigned buffer = value & 0x7f; 4 # while ((value >>= 7) > 0) { 5 # buffer <<= 8; 6 # buffer |= 0x80; 7 # buffer += value & 0x7f; 8 # } 9 # for ( ; ; ) { 10 # *dest++ = (unsigned char)buffer; 11 # if (buffer & 0x80) 12 # buffer >>= 8; 13 # else 14 # return dest; 15 # } 16 #} 17 18 .global putvlq #//Регистри: value = r0, dest = r1, buffer = r2 19 putvlq: #putVLQ(unsigned value, unsigned char *dest) { 20 0000 00304851 01F81B18 ANDI r2,r0,0x7F # unsigned buffer = value & 0x7f; 21 0008 00304851 00380A30 L1: SHRUI r0,r0,7 # while ((value >>= 7) > 0) { 22 0010 003048D1 01004014 BEQZ r0,L2 23 { ORI r3,r0,-0x80 # unsigned tmp = value | -0x80; 24 0018 03007840 41400430 SHLI r2,r2,8 } # buffer <<= 8; 25 { BFINS r2,r3,0,7 # buffer |= tmp & 0xff; 26 0020 C27000B6 FEFFFF27 J L1 } # } 27 L2: { ST1_ADD r1,r2,1 #___ for ( ; ; ) { 28 0028 83701CB5 2010C818 BFEXTU r3,r2,7,7 } #__ \___ *dest++ = (unsigned char)buffer; 29 0030 00304851 61004014 BEQZ r3,L3 #_ \____ if (buffer & 0x80) 30 { SHRUI r2,r2,8 # \ buffer >>= 8; 31 0038 82801460 FFFFFF27 J L2 } # \____ else return dest; 32 L3: { MOVE r0,r1 # } 33 0040 40F00751 E0766A28 JR lr } #} //Върни указателя към следващия байт в r0 IA-64 GAS putvlq.s page 1 1 //unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 2 //{ // (вж. Standard MIDI-File Format Spec. 1.1) 3 // unsigned buffer = value & 0x7f; 4 // while ((value >>= 7) > 0) { 5 // buffer <<= 8; 6 // buffer |= 0x80; 7 // buffer += value & 0x7f; 8 // } 9 // for ( ; ; ) { 10 // *dest++ = (unsigned char)buffer; 11 // if (buffer & 0x80) 12 // buffer >>= 8; 13 // else 14 // return dest; 15 // } 16 //} 17 18 .global putvlq ///Рег.: value = in0, dest = in1, buffer = loc1 19 putvlq: //putVLQ(unsigned value, unsigned char *dest) { 20 ALLOC loc0=ar.pfs,2,3,0,0 21 AND loc1=0x7F,in0 // unsigned buffer = value & 0x7f; 22 L1: SHR.U in0=in0,7 // while ((value >>= 7) > 0) { 23 0000 0010150A 800530FA 83584000 00000400 CMP.NE p6,p7=in0,r0 24 (p6) OR loc2=-0x80,in0 // unsigned tmp = value | -0x80; 25 0010 03000000 01000072 807029E0 000218E0 (p6) SHL loc1=loc1,8 // buffer <<= 8; 26 (p6) DEP loc1=loc2,loc1,0,8// buffer |= tmp & 0xff; 27 0020 C2200140 2EA2311A DDEE2963 441ADD4F (p6) BR L1 // } 28 L2: ST1 [in1]=loc1,1 //__ for ( ; ; ) { 29 TBIT.NZ p6,p7=loc1,7 //_ \__ *dest++ = (unsigned char)buffer; 30 0030 10000000 01000000 00020003 E0FFFF48 (p6) SHR.U loc1=loc1,8 //_\___ if (buffer & 0x80) buffer >>= 8; 31 0040 02088C42 80157070 8C0C2863 0419DD52 (p6) BR L2 // else return dest; 32 MOV r8=in1 // } 33 0050 10000000 01000000 00020003 F0FFFF48 BR.RET.SPTK rp //} //Върни указателя към следващия байт в r8 33 11400042 00210000 00020080 00008400 E2K GAS putvlq.s page 1 1 !unsigned char *putVLQ(unsigned value, unsigned char *dest) // запиши ВПД 2 !{ // (вж. Standard MIDI-File Format Spec. 1.1) 3 ! unsigned buffer = value & 0x7f; 4 ! while ((value >>= 7) > 0) { 5 ! buffer <<= 8; 6 ! buffer |= 0x80; 7 ! buffer += value & 0x7f; 8 ! } 9 ! for ( ; ; ) { 10 ! *dest++ = (unsigned char)buffer; 11 ! if (buffer & 0x80) 12 ! buffer >>= 8; 13 ! else 14 ! return dest; 15 ! } 16 !} 17 18 .global putvlq !/Рег.: value = %r0, dest = %r1, buffer = %r2 19 putvlq: !putVLQ(unsigned value, unsigned char *dest) 20 0000 01400000 000000F0 return %ctpr3 !{ 21 { andd %r0,0x7F,%r2 ! unsigned buffer = value & 0x7f; 22 0008 12400004 82D48001 02000040 00007F00 disp %ctpr1,L1 } 23 L1: { shrd %r0,7,%r0 ! while ((value >>= 7) > 0) { 24 0018 1200000C 80C7801B 60D48021 00007F00 cmpbedb %r0,0x7F,%pred0 } 25 0028 11000104 83D48005 000080FF 0000E004 ord %r0,-0x80,%r3 ? ~%pred0!unsigned tmp = value | -0x80; 26 { insfd %r2,8 << 6 | 56,%r3,%r2 ? ~%pred0 27 0038 22101104 600400C0 82D4826D 0000830B 00003802 0000E004 ct %ctpr1 ? ~%pred0 }! \__ buffer = buffer << 8 | tmp & 0xff; 28 0050 01400000 01000040 disp %ctpr1,L2 ! } 29 L2: { stb %r2,[%r1] !__ for ( ; ; ) { 30 addd %r1,1,%r1 ! *dest++ = (unsigned char)buffer; 31 0058 2300001C 81C18111 40D48223 82C08124 00000000 00008000 cmpandedb %r2,0x80,%pred0 }! if (buffer & 0x80) 32 { shrd %r2,8,%r2 ? ~%pred0! buffer >>= 8; 33 0070 12100104 600400C0 82C8821B 0000E004 ct %ctpr1 ? ~%pred0 } ! else return dest; 34 { ord %r1,0,%r0 ! } 35 0080 12100004 200C00C0 80C08105 00000000 ct %ctpr3 } !} //Върни указателя към следващия байт в r8 S/390x LISTING getipstr.s page 1 1 # Да се напише подпрограма, която да връща в регистър 2 IP-адреса (IPv4), 2 # получен от низа тип ASCIIZ с начален адрес, подаден в същия регистър. Низът 3 # е в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) 4 5 .global getipstr 6 getipstr: 7 0000 1744 L1: XR 4,4 # Нов текущ байт - започни натрупването от нулата 8 0002 E3502000 0090 L2: LLGC 5,0(2) # Зареди поредния символ и засега приеми, че е цифра 9 0008 A72B0001 AGHI 2,1 # Обнови адреса 10 000c A75BFFD0 AGHI 5,-'0' # Преобразувай го от ASCII в двоичнодесетичен 11 0010 A7440007 JL L3 # Не е цифра? Излез от вътрешния цикъл 12 0014 A74C000A MHI 4,10 # Измести текущата стойност с 1 десетичен разред наляво 13 0018 1E45 ALR 4,5 # Добави цифрата към нея 14 001a A7F4FFF4 J L2 # Продължи със следващия символ от низа 15 001e 89300008 L3: SLL 3,8 # Направи място за още един байт 16 0022 1634 OR 3,4 # Запиши текущия байт най-отдясно 17 0024 EC56FFEE D07C CGIJNE 5,-'0',L1#Нулев терминатор ли е бил той или разделител ('.')? 18 002a B9040023 LGR 2,3 # Бил е нулев терминатор – върни IP-адреса в рег. 2 19 002e 07FE BR 14 AMD64 GAS getipstr.s page 1 1 # Да се напише подпрограма, която да връща в регистър EAX IP-адреса (IPv4), 2 # получен от низа тип ASCIIZ с начален адрес, подаден в регистър RDI. Низът е 3 # в десетичен формат с разделител между байтовете точка (пример: 192.92.129.2). 4 5 .intel_syntax noprefix 6 .global getipstr 7 getipstr: 8 0000 4889FE MOV RSI,RDI # Началният адрес е удобно да бъде в RSI заради LODSB 9 0003 31C0 L1: XOR EAX,EAX # Нов текущ байт - започни натрупването от нула 10 0005 99 CDQ 11 0006 6BD20A L2: IMUL EDX,EDX,10 # Удесетори декущата стойност 12 0009 00C2 ADD DL,AL # Добави цифрата към нея 13 000b AC LODSB # Зареди поредния символ и приеми, че е цифра 14 000c 2C30 SUB AL,'0' # Преобразувай от ASCII в двоичнодесетичен 15 000e 73F6 JAE L2 # Цифра? Продължи със следващия символ от низа 16 0010 C1E108 SHL ECX,8 # Направи място за текущия байт 17 0013 88D1 MOV CL,DL # и го запиши най-отдясно в IP-адреса 18 0015 3CD0 CMP AL,-'0' # Нулев терминатор ли е бил този байт? 19 0017 75EA JNE L1 # Не, значи е бил разделител ('.') 20 0019 91 XCHG EAX,ECX # Върни IP-адреса в EAX 21 001a C3 RET AARCH64 GAS getipstr.s page 1 1 // Да се напише подпрограма, която да връща в регистър W0 IP-адреса (IPv4), 2 // получен от низа тип ASCIIZ с начален адрес, подаден в регистър X0. Низът е 3 // в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2). 4 5 .global getipstr 6 getipstr: 7 0000 44018052 MOV W4,#10 // Основа на бройната система на низа 8 0004 E2031F2A L1: MOV W2,WZR // Нов текущ байт - започни натрупването от нулата 9 0008 03144038 L2: LDRB W3,[X0],#1// Зареди поредния символ и засега приеми, че е цифра 10 000c 63C00071 SUBS W3,W3,#'0'// Преобразувай го от ASCII в двоичнодесетичен 11 0010 63000054 BLO L3 // Цифра? 12 0014 820C021B MADD W2,W4,W2,W3//Да, добави я към удесеторената текуща стойност 13 0018 FCFFFF17 B L2 // и продължи със следващия символ от низа 14 001c 4120010B L3: ADD W1,W2,W1,LSL #8// Не, добави новия байт към натрупания IP-адрес 15 0020 7FC00031 CMP W3,#-'0' // Нулев терминатор ли е бил този байт? 16 0024 01FFFF54 BNE L1 // Не, значи е бил разделител ('.') 17 0028 E003012A MOV W0,W1 // Да, върни IP-адреса в X0 18 002c C0035FD6 RET ARC GAS getipstr.s page 1 1 # Да се напише подпрограма, която да връща в регистър r0 IP-адреса (IPv4), 2 # получен от низа тип ASCIIZ с начален адрес, подаден в същия регистър. Низът 3 # е в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) 4 5 .global getipstr 6 getipstr: 7 0000 00DA L1: MOVL_S r2,0 # Нов текущ байт - започни натрупването от нулата 8 0002 0110 8304 L2: LDB.AB r3,[r0,1] # Зареди поредния символ и засега приеми, че е цифра 9 0006 425B 038C SUBL.F r3,r3,'0' # Преобразувай го от ASCII в двоичнодесетичен 10 000a F05A A602 MPYL.HS r2,r2,10 # Ако символът е бил цифра, измести текущия байт с 1 11 000e C05A C600 ADDL.HS r2,r2,r3 # десетичен разред наляво, добави към него тая цифра 12 0012 79F7 BHS_S L2 # и продължи със следващия символ от низа 13 0014 6059 0102 ASLL r1,r1,8 # Иначе направи място за новия байт 14 0018 4179 ADDL_S r1,r1,r2 # и го добави към натрупания IP-адрес 15 001a E90B 098F FFFF D0FF BRNEL r3,-'0',L1 # Ако силволът не е бил терминатор (0), а разделител 16 0022 2440 MOVL_S r0,r1 # ('.'), продължи цикъла, иначе върни IP-адреса в r0 17 0024 E07E J_S [blink] PPC LISTING getipstr.s page 1 1 # Да се напише подпрограма, която да връща в регистър r3 IP-адреса (IPv4), 2 # получен от низа тип ASCIIZ с начален адрес, подаден в същия регистър. Низът 3 # е в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) 4 5 .global getipstr 6 getipstr: 7 0000 3883FFFF addi r4,r3,-1# Компенсирай преинкрементната адресация 8 0004 38A00000 L1: li r5,0 # Нов текущ байт - започни натрупването от нулата 9 0008 8CC40001 L2: lbzu r6,1(r4)# Зареди поредния символ и засега приеми, че е цифра 10 000c 34C6FFD0 addic. r6,r6,-'0#Преобразувай го от ASCII в двоичнодесетичен 11 0010 41800010 blt L3 # Не е цифра? Излез от вътрешния цикъл 12 0014 1CA5000A mulli r5,r5,10# Измести текущата стойност с 1 десетичен разред наляво 13 0018 7CA53214 add r5,r5,r6# Добави цифрата към нея 14 001c 4BFFFFEC b L2 # Продължи със следващия символ от низа 15 0020 786345E4 L3: sldi r3,r3,8 # Направи място за още един байт 16 0024 7C632B78 or r3,r3,r5# Запиши текущия байт най-отдясно 17 0028 2C26FFD0 cmpdi r6,-'0 # Нулев терминатор ли е бил този байт? 18 002c 4082FFD8 bne L1 # Не, значи е бил разделител ('.') 19 0030 4E800020 blr # Да, върни управлението SPARC GAS getipstr.s page 1 1 ! Да се напише подпрограма, която да връща в регистър %o0 IP-адреса (IPv4), 2 ! получен от низа тип ASCIIZ с начален адрес, подаден в същия регистър. Низът 3 ! е в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) 4 5 .global getipstr 6 getipstr: 7 0000 94100000 L1: clr %o2 ! Нов текущ байт - започни натрупването от нулата 8 0004 D60A0000 L2: ldub [%o0],%o3 ! Зареди поредния символ и засега приеми, че е цифра 9 0008 96A2E030 subcc %o3,'0',%o3! Преобразувай символа от ASCII в двоичнодесетичен 10 000c 0A680005 bcs %xcc,L3 ! Не е цифра? Излез от вътрешния цикъл 11 0010 90022001 inc %o0 ! Обнови адреса (изпълнява се преди „bcs“!) 12 0014 944AA00A mulx %o2,10,%o2!Измести текущата стойност вляво с 1 десетичен разред 13 0018 10BFFFFB ba L2 ! Зареди следващия символ (изпълнява се след „add“!) 14 001c 9402800B add %o2,%o3,%o2! Добави цифрата към нея 15 0020 932A7008 L3: sllx %o1,8,%o1 ! Направи място за още един байт 16 0024 80A2FFD0 cmp %o3,-'0' ! Нулев терминатор ли е бил този байт? 17 0028 126FFFF6 bne %xcc,L1 ! Не, значи е бил разделител ('.') 18 002c 9212400A or %o1,%o2,%o1!Да, запиши байта вдясно (изпълнява се преди „bne“!) 19 0030 81C3E008 retl 20 0034 90100009 mov %o1,%o0 ! Върни адреса в %o0 (изпълнява се преди „retl“!) MIPS LISTING getipstr.s page 1 1 # Да се напише подпрограма, която да връща в регистър $2 IP-адреса (IPv4), 2 # получен от низа тип ASCIIZ с начален адрес, подаден в регистър $4. Низът е 3 # в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) 4 5 .ent getipstr 6 .global getipstr 7 getipstr: 8 0000 2408000A LI $8,10 # Основа на бройната система 9 0004 2407FFD0 LI $7,-'0' # Подготви преобразуването от ASCII 10 0008 24060000 L1: LI $6,0 # Нов текущ байт - започни натрупването от нулата 11 000c 90850000 L2: LBU $5,0($4)# Зареди поредния символ и засега приеми, че е цифра 12 0010 64840001 DADDIU $4,$4,1 # Обнови адреса 13 0014 00A7282D DADDU $5,$5,$7# Преобразувай символа от ASCII в двоичнодесетичен 14 0018 04A00004 00000000 BLTZ $5,L3 # Не е цифра? Излез от вътрешния цикъл 15 0020 70C83002 MUL $6,$6,$8# Измести текущата стойност вляво с 1 десетичен разред 16 DADDU $6,$6,$5# Добави цифрата към нея 17 0024 1000FFF9 00C5302D B L2 # Продължи със следващия символ от низа 18 002c 00021238 L3: DSLL $2,$2,8 # Направи място за още един байт 19 OR $2,$2,$6# Запиши текущия байт най-отдясно 20 0030 14A7FFF5 00461025 BNE $5,$7,L1# Байтът не е бил нулев терминатор, а разделител ('.') 21 0038 03E00008 00000000 JR $31 # Върни управлението 22 .end getipstr RISC-V LISTING getipstr.s page 1 1 # Да се напише подпрограма, която да връща в регистър a0 IP-адреса (IPv4), 2 # получен от низа тип ASCIIZ с начален адрес, подаден в същия регистър. Низът 3 # е в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) 4 5 .global getipstr 6 getipstr: 7 0000 1307A000 LI a4,10 # Основа на бройната система 8 0004 930600FD LI a3,-'0' # Подготви преобразуването от ASCII 9 0008 13060000 L1: LI a2,0 # Нов текущ байт - започни натрупването от нулата 10 000c 83450500 L2: LBU a1,0(a0)# Зареди поредния символ и засега приеми, че е цифра 11 0010 13051500 ADDI a0,a0,1 # Обнови адреса 12 0014 B385D500 ADD a1,a1,a3# Преобразувай символа от ASCII в двоичнодесетичен 13 0018 63C80500 BLTZ a1,L3 # Не е цифра? Излез от вътрешния цикъл 14 001c 3306E602 MUL a2,a2,a4# Измести текущата стойност вляво с 1 десетичен разред 15 0020 3306B600 ADD a2,a2,a1# Добави цифрата към нея 16 0024 6FF09FFE J L2 # Продължи със следващия символ от низа 17 0028 93978700 L3: SLLI a5,a5,8 # Направи място за още един байт 18 002c B3E7C700 OR a5,a5,a2# Запиши текущия байт най-отдясно 19 0030 E39CD5FC BNE a1,a3,L1# Байтът не е бил нулев терминатор, а разделител ('.') 20 0034 13850700 MV a0,a5 # Върни IP-адреса в a0 21 0038 67800000 RET # Върни управлението LOONGARCH64 GAS getipstr.s page 1 1 # Да се напише подпрограма, която да връща в регистър r4 IP-адреса (IPv4), 2 # получен от низа тип ASCIIZ с начален адрес, подаден в същия регистър. Низът 3 # е в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) 4 5 .global getipstr 6 getipstr: 7 0000 08288003 ORI $r8,$r0,10 # Основа на бройната система 8 0004 0740FF02 ADDI.D $r7,$r0,-'0'# Подготви преобразуването от ASCII 9 0008 06001500 L1: OR $r6,$r0,$r0# Нов текущ байт - започни натрупването от нулата 10 000c 8500002A L2: LD.BU $r5,$r4,0 # Зареди поредния символ и засега приеми, че е цифра 11 0010 8404C002 ADDI.D $r4,$r4,1 # Обнови адреса 12 0014 A59C1000 ADD.D $r5,$r5,$r7# Преобразувай символа от ASCII в двоичнодесетичен 13 0018 A0100060 BLTZ $r5,L3 # Не е цифра? Излез от вътрешния цикъл 14 001c C6A01D00 MUL.D $r6,$r6,$r8# Измести текущия байт вляво с 1 десетичен разред 15 0020 C6941000 ADD.D $r6,$r6,$r5# Добави цифрата към нея 16 0024 FFEBFF53 B L2 # Продължи със следващия символ от низа 17 0028 29214100 L3: SLLI.D $r9,$r9,8 # Направи място за още един байт 18 002c 29191500 OR $r9,$r9,$r6# Запиши текущия байт най-отдясно 19 0030 A7D8FF5F BNE $r5,$r7,L1#Байтът не е бил нулев терминатор, а разделител ('.') 20 0034 24011500 OR $r4,$r9,$r0# Върни IP-адреса в r4 21 0038 2000004C JIRL $r0,$r1,0 # Да се напише подпрограма, която да връща в регистър $0 IP-адреса (IPv4), # получен от низа тип ASCIIZ с начален адрес, подаден в регистър $16. Низът е getipstr.o: file format ecoff-littlealpha # в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) Disassembly of section .text: .ent getipstr .globl getipstr 0000000000000000 : getipstr: 0: 00 00 5f 20 lda t1,0(zero) L1: lda $2,0($31)# Нов текущ байт - започни натрупването от нулата 4: 00 00 30 28 ldbu t0,0(a0) L2: ldbu $1,0($16)# Зареди поредния символ и засега приеми, че е цифра 8: 21 15 26 40 subq t0,0x30,t0 addq $16,1,$16# Обнови адреса c: 10 34 00 42 addq a0,0x1,a0 subq $1,48,$1 # Преобразувай символа от ASCII в двоичнодесетичен 10: 04 00 20 e8 blt t0,24 blt $1,L3 # Не е цифра? Излез от вътрешния цикъл 14: 42 04 42 40 s4addq t1,t1,t1 mulq $2,10,$2 # Измести текущата стойност вляво с 1 десетичен разред 18: 02 04 42 40 addq t1,t1,t1 1c: 02 04 41 40 addq t1,t0,t1 addq $2,$1,$2 # Добави цифрата към нея 20: f8 ff ff c3 br 4 br $31,L2 # Продължи със следващия символ от низа 24: 20 17 01 48 sll v0,0x8,v0 L3: sll $0,8,$0 # Направи място за още един байт 28: 01 14 26 40 addq t0,0x30,t0 bis $0,$2,$0 # Запиши текущия байт най-отдясно 2c: 00 04 02 44 or v0,t1,v0 addq $1,48,$1 #Символът не е бил терминатор (0), а разделител ('.')? 30: f3 ff 3f f4 bne t0,0 bne $1,L1 # Да, продължи със следващия 34: 01 80 fa 6b ret zero,(ra),0x1 ret # Не, върни IP-адреса в $0 38: 1f 04 ff 47 nop .end getipstr 3c: 00 00 fe 2f unop GAS for MMIX getipstr.s page 1 1 % Да се напише подпрограма, която да връща в регистър $0 IP-адреса (IPv4), 2 % получен от низа тип ASCIIZ с начален адрес, подаден в регистър $0. Низът е 3 % в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) 4 5 .global getipstr 6 getipstr: 7 0000 C6020202 L1: XOR $2,$2,$2 % Нов текущ байт - започни натрупването от нулата 8 0004 83010000 L2: LDBU $1,$0,0 % Зареди поредния символ и засега приеми, че е цифра 9 0008 23000001 ADDU $0,$0,1 % Обнови адреса 10 000c 27010130 SUBU $1,$1,'0'% Преобразувай символа от ASCII в двоичнодесетичен 11 0010 40010004 BN $1,L3 % Не е цифра? Излез от вътрешния цикъл 12 0014 1B02020A MULU $2,$2,10 % Измести текущата стойност вляво с 1 десетичен разред 13 0018 22020201 ADDU $2,$2,$1 % Добави цифрата към нея 14 001c F1FFFFFA JMP L2 % Продължи със следващия символ от низа 15 0020 3B030308 L3: SLU $3,$3,8 % Направи място за още един байт 16 0024 C0030302 OR $3,$3,$2 % Запиши текущия байт най-отдясно 17 0028 23010130 ADDU $1,$1,'0'%Символът не е бил терминатор (0), а разделител ('.')? 18 002c 4B01FFF5 BNZ $1,L1 % Да, продължи със следващия 19 0030 C1000300 OR $0,$3,0 % Не, върни IP-адреса в $0 20 0034 F8010000 POP 1,0 HPPA64 LISTING getipstr.s page 1 1 ; Да се напише подпрограма, която да връща в регистър %R28 IP-адреса (IPv4), 2 ; получен от низа тип ASCIIZ с начален адрес, подаден в регистър %R26. Низът 3 ; е в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) 4 5 .global getipstr 6 getipstr: ; %R26 = адрес на низа, %R25 = байт, %R24 = символ 7 0000 34190000 L1: LDI 0,%R25 ; Нов байт - започни натрупването от нулата 8 0004 0F421038 L2: LDB,MA 1(%R26),%R24; Зареди поредния символ. Засега приеми, че е цифра 9 0008 C778C018 BB,>= %R24,27,L3 ; '.' (2E) или 0? Байтът готов (пров.се преди DEPWI 10 000c D7001C9E DEPWI 0,27,2,%R24 ; Преобразувай от ASCII (изпълнява се преди „BB“!) 11 0010 0B390A99 SHLADD,L %R25,2,%R25,%R25; Умножи текущата стойност на байта по 5, ... 12 0014 E81F1FD5 B L2 ; (продължи със следващия символ от низа) 13 0018 0B190A59 SHLADD,L %R25,1,%R24,%R25; удвои я и добави цифрата (изп.се преди „B“!) 14 001c D79C0908 L3: DEPW,Z %R28,23,24,%R28; Измести натрупания IP-адрес с 8 бита наляво... 15 0020 8F003FB5 CMPIB,<> 0,%R24,L1 ; (ако символът е бил '.', а не 0, продължи) 16 0024 0B3C061C ADD %R28,%R25,%R28; и добави новия байт (изпълн. се преди „CMPIB“!) 17 0028 E840D002 BVE,N (%R2) ; Върни IP-адреса в %R28 TILE-Gx GAS getipstr.s page 1 1 # Да се напише подпрограма, която да връща в регистър r1 IP-адреса (IPv4), 2 # получен от низа тип ASCIIZ с начален адрес, подаден в регистър r0. Низът е 3 # в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) 4 5 .global getipstr 6 getipstr: 7 0000 00304851 E2570818 MOVEI r4,10 # Подготви основата на бройната система като множител 8 0008 003048D1 E1FF3B28 L1: MOVE r3,zero # Нов текущ байт - започни натрупването от нулата 9 0010 00304851 01084018 L2: LD1U_ADD r2,r0,1 # Зареди 1 символ, приеми, че е цифра и обнови адреса 10 0018 00304851 41800E18 ADDI r2,r2,-'0'#Преобразувай символа от ASCII в двоичнодесетичен 11 0020 003048D1 41004017 BLTZ r2,L3 # Не е цифра? Излез от вътрешния цикъл 12 0028 C340F850 00306A28 MUL_LU_LU r3,r3,r4#Измести текущата стойност вляво с 1 десетичен разред 13 { ADD r3,r3,r2 # Добави цифрата към нея 14 0030 C3200C50 FEFFFF27 J L2 } # Продължи със следващия символ от низа 15 0038 003048D1 20400430 L3: SHLI r1,r1,8 # Направи място за още един байт 16 { OR r1,r1,r3 # Запиши текущия байт най-отдясно 17 0040 41300451 41800918 ADDI r2,r2,'0'}#Символът не е бил терминатор (0),а разделител ('.')? 18 0048 00304851 5CF8BF17 BNEZT r2,L1 # Да, продължи със следващия 19 { MOVE r0,r1 # Не, върни IP-адреса в r0 20 0050 40F00751 E0766A28 JR lr } IA-64 GAS getipstr.s page 1 1 // Да се напише подпрограма, която да връща в регистър r8 IP-адреса (IPv4), 2 // получен от низа тип ASCIIZ с начален адрес, подаден в регистър in0. Низът е 3 // в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) 4 5 .global getipstr 6 getipstr: 7 ALLOC loc0=ar.pfs,1,3,0,0 8 L1: ADD loc2=r0,r0 // Нов текущ байт - започни натрупването от нулата 9 L2: LD1 loc1=[in0],1//Зареди поредния символ; засега приеми, че е цифра 10 0000 00081108 80050000 00020000 00000400 ADD loc1=-'0',loc1 // Преобразувай от ASCII в двоичнодесетичен код 11 0010 00180100 00200000 00020000 00000400 CMP.GE p6,p7=loc1,r0 // Не е цифра? Излез от вътрешния цикъл 12 0020 0B100540 00142082 8A7E4600 00000400 (p6) SHL loc2=loc2,1 // Измести текущата стойност вляво с 1 13 (p6) SHLADD loc2=loc2,2,loc2// десетичен разред (т.е., умножи я по 10) 14 0030 0B388800 06300000 00020063 34F2F953 (p6) ADD loc2=loc2,loc1 // Добави цифрата към нея 15 (p6) BR L2 // Продължи със следващия символ от низа 16 0040 CA188D46 11A0311A 89004000 00000400 SHL r8=r8,8 // Направи място за още един байт 17 OR r8=r8,loc2 // Запиши текущия байт най-отдясно 18 0050 10000000 01000000 00020003 D0FFFF48 CMP.NE p6,p7=-'0',loc1 // Символът не е бил терм. (0), а разд. ('.')? 19 0060 02000000 01008040 DCEE2900 81183980 (p6) BR L1 // Да, продължи със следващия 20 0070 13384045 06BB01D0 FF7F2480 00008400 BR.RET.SPTK rp // Не, върни IP-адреса в r8 E2K GAS getipstr.s page 1 1 ! Да се напише подпрограма, която да връща в регистър r0 IP-адреса (IPv4), 2 ! получен от низа тип ASCIIZ с начален адрес, подаден в същия регистър. Низът 3 ! е в десетичен формат с разделител между байтовете точка (напр. 192.92.129.2) 4 5 .global getipstr 6 getipstr: 7 0000 01400000 000000F0 return %ctpr3 ! Подготви връщането към извикващата функция 8 L1: { disp %ctpr1,L2 ! и прехода в началото на вътрешния цикъл 9 0008 12400004 82828209 02000040 00000000 xord %r2,%r2,%r2 } ! Нов текущ байт - започни натрупване от нулата 10 L2: { ldb [%r0],%r1 ! Зареди поредния символ 11 0018 1200000C 81C08064 80C18011 00000000 addd %r0,1,%r0 } ! Засега приеми, че е цифра и обнови адреса 12 { cmpedb %r1,0,%pred1 ! Символът е терминатор 0, а не разделител('.') 13 cmpbdb %r1,'0',%pred0 ! Не е цифра? Ще излезем от вътрешния цикъл 14 0028 2300001C 41C08121 20D48121 81D48113 00000000 00003000 subd %r1,'0',%r1 } ! Преобразувай от ASCII в двоичнодесетичен код 15 0040 11001104 82CA8221 0000C001 0000E004 muld %r2,10,%r2 ? ~%pred0 ! Измести текущия байт вляво с 1 десетичен 16 { addd %r2,%r1,%r2 ? ~%pred0! разред и добави новата цифра към него 17 0050 12100104 600400C0 82818211 0000E004 ct %ctpr1 ? ~%pred0}!Продължи със следващия символ от низа 18 { disp %ctpr1,L1 ! Подготви прехода в началото на външния цикъл 19 0060 12402008 83C88319 F5FFFF4F 0000820A shl_addd %r3,8,%r2,%r3 }! Направи място за този байт и го запиши вдясно 20 0070 01100000 610400C0 ct %ctpr1 ? ~%pred1!Символът е разделител, продължи със следващия 21 { ord %r3,0,%r0 ! Символът е тарминатор, върни IP-адреса в r0 22 0078 12100004 200C00C0 80C08305 00000000 ct %ctpr3 } S/390x LISTING putipstr.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър 3, 2 # низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 # байтовете точка, получен от IP-адрес (IPv4), подаден в регистър 2. 4 5 .global putipstr 6 putipstr: 7 0000 E360F010 0024 STG 6,16(15) # Съхрани използвания регистър (LNUX-1007-02) 8 0006 C00F2E2E 2E00 LLILF 0,'.' << 24 |'.' << 16 | '.' << 8# 3 разделителя и 1 термин.(0) 9 000c EB520018 000C L1: SRLG 5,2,24 # Зареди следващ байт (от старши към младши) 10 0012 89200008 SLL 2,8 # Измести IP-адреса с 1 байт наляво 11 0016 EC5C000E 097C CGIJNH 5,9,L3 # Само единици? Запиши ги без нули пред тях 12 001c EC5C0007 637C CGIJNH 5,99,L2 # Няма стотици? " " " " " " " 13 0022 A7190064 LGHI 1,100 # Подготви делителя 14 0026 A7650017 BRAS 6,Digit # Получи и запиши цифрите на стотиците 15 002a A719000A L2: LGHI 1,10 16 002e A7650013 BRAS 6,Digit # Направи същото и с десетиците, 17 0032 A7190001 L3: LGHI 1,1 # и с единиците 18 0036 A765000F BRAS 6,Digit 19 003a 88000008 SRL 0,8 # Подготви следващия разделител или терминатор 20 003e 42003000 STC 0,0(3) # и го запиши в низа 21 0042 A73B0001 AGHI 3,1 # Обнови указателя 22 0046 EC06FFE3 007C CGIJNE 0,0,L1 # Ако има още байтове, премини към следващия 23 004c E360F010 0004 LG 6,16(15) # Възстанови съхранения регистър 24 0052 07FE BR 14 # и се върни в извикващата програма 25 26 0054 1744 Digit: XR 4,4 # Старшата дума на делимото трябва да е 0! 27 0056 1D41 DR 4,1 # Рег. 5 = поредната цифра, рег. 4 = следващите 28 0058 A75B0030 AGHI 5,'0' # Преобразувай цифрата в ASCII-код 29 005c 42503000 STC 5,0(3) # и я запиши в низа 30 0060 A73B0001 AGHI 3,1 # Обнови указателя 31 0064 1854 LR 5,4 # Остатъкът ще бъде следващото делимо 32 0066 07F6 BR 6 AMD64 GAS putipstr.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър RSI, 2 # низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 # байтовете точка, получен от IP-адрес (IPv4), подаден в регистър EDI. 4 5 .intel_syntax noprefix 6 .global putipstr 7 putipstr: 8 0000 89FA MOV EDX,EDI # EDX = IP-адрес 9 0002 4889F7 MOV RDI,RSI # RDI = начален адрес на низа 10 0005 B9002E2E 2E MOV ECX,'.' << 24 | '.' << 16 | '.' << 8 # Разделители и терминатор 11 000a C1C208 L1: ROL EDX,8 # Подготви следващия байт, от старши към младши 12 000d 31C0 XOR EAX,EAX 13 000f 88D0 MOV AL,DL # Байтът трябва да е в AX заради командата DIV 14 0011 3C09 CMP AL,9 # Само единици ли имаме? 15 0013 7617 JBE L3 # Да, запиши ги направо, без нули пред тях 16 0015 3C63 CMP AL,99 # Не, само десетици и единици ли имаме? 17 0017 760A JBE L2 # Да, запиши ги направо, без нула пред тях 18 0019 B264 MOV DL,100 # Подготви делителя 19 001b F6F2 DIV DL # AL: 100тици, AH: 10ици, 1ици 20 001d 0430 ADD AL,'0' # Преобразувай стотиците в 21 001f AA STOSB # ASCII-код и го запиши в низа 22 0020 C1E808 SHR EAX,8 # AL = десетици и единици 23 0023 B20A L2: MOV DL,10 # Подготви делителя 24 0025 F6F2 DIV DL # AL = десетици, AH = единици 25 0027 0430 ADD AL,'0' # Преобразувай десетиците в 26 0029 AA STOSB # ASCII-код и го запиши в низа 27 002a 88E0 MOV AL,AH # AL = единици 28 002c 0430 L3: ADD AL,'0' # Преобразувай единиците в ASCII-код 29 002e C1E908 SHR ECX,8 # Πocлeдeн бaйт? 30 0031 88CC MOV AH,CL # (Πoдгoтви paздeлитeля кaтo cлeдвaщ cимвoл 31 0033 66AB STOSW # и зaпиши eдиницитe и paздeлитeля в низa) 32 0035 75D3 JNZ L1 # Не, премини към обработка на следващия байт 33 0037 C3 RET # Да, върни се в извикващата програма AARCH64 GAS putipstr.s page 1 1 // Да се напише подпрограма, която да записва от адрес, подаден в регистър X1, 2 // низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 // байтовете точка, получен от IP-адрес (IPv4), подаден в регистър W0. 4 5 .global putipstr 6 putipstr: 7 0000 E6031EAA MOV X6,LR // Съхрани LR, защото BL ще го промени! 8 0004 C2020018 LDR W2,='.' << 24 |'.' << 16 | '.' << 8 9 0008 037C1853 L1: LSR W3,W0,#24 // Зареди следващ байт (от старши към младши) 10 000c 005C1853 LSL W0,W0,#8 // Измести IP-адреса с 1 байт наляво 11 0010 7F240071 CMP W3,#9 // Само единици ли имаме? 12 0014 E9000054 BLS L3 // Да, запиши ги направо, без нули пред тях 13 0018 7F8C0171 CMP W3,#99 // Не, само десетици и единици ли имаме? 14 001c 69000054 BLS L2 // Да, прескочи стотиците 15 0020 840C8052 MOV W4,#100 // Не, получи и запиши цифрите на стотиците 16 0024 09000094 BL DIGIT 17 0028 44018052 L2: MOV W4,#10 // Направи същото и с десетиците 18 002c 07000094 BL DIGIT 19 0030 63C00011 L3: ADD W3,W3,#'0' // Преобразувай цифрата на единиците в ASCII 20 0034 23140038 STRB W3,[X1],#1 // Запиши ASCII-кода на единиците 21 0038 427C0853 LSR W2,W2,#8 // Последен байт? 22 003c 22140038 STRB W2,[X1],#1 // (Запиши разделителя или терминатора в низа) 23 0040 42FEFF35 CBNZ W2,L1 // Не: премини към обработка на следващия байт 24 0044 C0001FD6 BR X6 // Да: върни управлението 25 26 0048 6508C41A DIGIT: UDIV W5,W3,W4 // W5 = поредната цифра 27 004c 838C051B MSUB W3,W4,W5,W3 // W3 = следващите цифри във вид на остатък 28 0050 A5C00011 ADD W5,W5,#'0' // Преобразувай цифрата в ASCII-код 29 0054 25140038 STRB W5,[X1],#1 // и я запиши в низа 30 0058 C0035FD6 RET 30 002E2E2E ARC GAS putipstr.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър r1, 2 # низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 # байтовете точка, получен от IP-адрес (IPv4), подаден в регистър r0. 4 5 .global putipstr 6 putipstr: 7 0000 C742 2E2E 002E MOVL_S r2,'.' << 24 |'.' << 16 | '.' << 8 8 0006 2D58 030F 0000 D801 L1: XBFUL r3,r0,(8 - 1) << 6 | 24# Зареди нов байт (от старши към младши) 9 000e 6058 0002 ASLL r0,r0,8 # Измести IP-адреса с 1 байт наляво 10 0012 330B 9C02 BRLOL r3,10,L3 # Само единици? Запиши ги без нули пред тях 11 0016 1F0B 0C0F 0000 6400 BRLOL r3,100,L2 # Не, само десетици и единици ли имаме? 12 001e 255B 050F 0000 6400 DIVUL r5,r3,100 # Не, r5 = цифрата на стотиците 13 0026 A95B 0109 REMUL r3,r3,100 # r3 = следващите цифри във вид на остатък 14 002a 405D 050C ADDL r5,r5,'0' # Преобразувай цифрата на стотиците в ASCII-код 15 002e 0119 5201 STB.AB r5,[r1,1] # и го запиши в низа 16 0032 655B 8502 L2: DIVUL r5,r3,10 # r5 = цифрата на десетиците 17 0036 695B 8302 REMUL r3,r3,10 # r3 = цифрата на единиците във вид на остатък 18 003a 405D 050C ADDL r5,r5,'0' # Преобразувай цифрата на десетиците в ASCII- 19 003e 0119 5201 STB.AB r5,[r1,1] # код и го запиши в низа 20 0042 405B 030C L3: ADDL r3,r3,'0' # Преобразувай цифрата на единиците " " " 21 0046 0119 D200 STB.AB r3,[r1,1] # Запиши ASCII-кода на единиците 22 004a 615A 0282 LSRL.F r2,r2,8 # Последен байт? 23 004e 0119 9200 STB.AB r2,[r1,1] # (Запиши разделителя или терминатора в низа) 24 0052 DBF5 BNE_S L1 # Не: премини към обработка на следващия байт 25 0054 E07E J_S [blink] # Да: върни управлението PPC LISTING putipstr.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър r4, 2 # низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 # байтовете точка, получен от IP-адрес (IPv4), подаден в регистър r3. 4 5 .global putipstr 6 putipstr: 7 0000 7D2802A6 mflr r9 # Съхрани lr, защото bl ще го промени! 8 0004 3884FFFF addi r4,r4,-1 # Компенсирай преинкрементната адресация 9 0008 3CA02E2E lis r5,'.' << 8 | '.' 10 000c 38A52E00 addi r5,r5,'.' << 8 # Подготви разделителите и терминатора ('\0') 11 0010 78664622 L1: rldicl r6,r3,40,56 # Зареди следващ байт (от старши към младши) 12 0014 786345E4 sldi r3,r3,8 # Измести IP-адреса с 1 байт наляво 13 0018 28260009 cmpldi r6,9 # Само единици ли имаме? 14 001c 40810018 ble L2 # Да, запиши ги направо, без нули пред тях 15 0020 28260063 cmpldi r6,99 # Има ли стотици? 16 0024 38E00064 li r7,100 # (подготви делителя) 17 0028 41810029 bgtl Digit # Ако да, запиши първо тях 18 002c 38E0000A li r7,10 # Направи същото и с десетиците 19 0030 48000021 bl Digit 20 0034 38C60030 L2: addi r6,r6,'0 # Преобразувай цифрата на единиците в ASCII 21 0038 9CC40001 stbu r6,1(r4) # и я запиши в низа, обновявайки указателя 22 003c 78A5C203 srdi. r5,r5,8 # Последен байт? 23 0040 9CA40001 stbu r5,1(r4) # (Запиши разделителя или терминатора в низа) 24 0044 4082FFCC bne L1 # Не, премини към обработка на следващия байт 25 0048 7D2803A6 mtlr r9 # Да, възстанови lr 26 004c 4E800020 blr # и върни управлението 27 28 0050 7D063B92 Digit: divdu r8,r6,r7 # r8 = поредната цифра 29 0054 7CE839D2 mulld r7,r8,r7 30 0058 7CC73050 subf r6,r7,r6 # r6 = следващите цифри във вид на остатък 31 005c 39080030 addi r8,r8,'0 # Преобразувай цифрата в ASCII-код 32 0060 9D040001 stbu r8,1(r4) # и я запиши в низа 33 0064 4E800020 blr SPARC GAS putipstr.s page 1 1 ! Да се напише подпрограма, която да записва от адрес, подаден в регистър %o1, 2 ! низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 ! байтовете точка, получен от IP-адрес (IPv4), подаден в регистър %o0. 4 5 .global putipstr 6 putipstr: 7 0000 8210000F mov %o7,%g1 ! Съхрани %o7, защото „call“ ще го промени! 8 0004 150B8B8B 9412A200 setx '.' << 24 |'.' << 16 | '.' << 8,%o3,%o2 9 000c 97322018 L1: srl %o0,24,%o3 ! Зареди следващ байт (от старши към младши) 10 0010 912A3008 sllx %o0,8,%o0 ! Измести IP-адреса с 1 байт наляво 11 0014 80A2E009 cmp %o3,9 ! Само единици ли имаме? 12 0018 08680008 bleu %xcc,L3 ! Да, запиши ги направо, без нули пред тях 13 001c 80A2E063 cmp %o3,99 ! Има ли стотици? 14 0020 08680004 bleu %xcc,L2 ! Не, прескочи стотиците 15 0024 9A102064 mov 100,%o5 ! (подготви делителя; изпълнява се преди bleu) 16 0028 4000000C call Digit ! Да, запиши първо тях 17 002c 01000000 nop 18 0030 4000000A L2: call Digit ! Направи същото и с десетиците, 19 0034 9A10200A mov 10,%o5 ! („mov“ се изпълнява преди „call“) 20 0038 40000008 L3: call Digit ! и с единиците 21 003c 9A102001 mov 1,%o5 ! („call“ се изпълнява след „mov“) 22 0040 9532B008 srlx %o2,8,%o2 ! Подготви следващия разделител или терминатор 23 0044 D42A4000 stb %o2,[%o1] ! (запиши разделителя или терминатора в низа) 24 0048 0AFABFF1 brnz %o2,L1 ! Ако има още байтове, премини към следващия 25 004c 92026001 add %o1,1,%o1 ! (обнови указателя; изпълнява се преди „brnz“) 26 0050 81C06008 jmpl %g1+8,%g0 ! Да - върни се в извикващата програма 27 0054 01000000 nop 28 29 0058 986AC00D Digit: udivx %o3,%o5,%o4 ! %o4 = поредната цифра 30 005c 9A4B000D mulx %o4,%o5,%o5 31 0060 9622C00D sub %o3,%o5,%o3 ! %o3 = следващите цифри във вид на остатък 32 0064 98032030 add %o4,'0',%o4 ! Преобразувай цифрата в ASCII-код 33 0068 D82A4000 stb %o4,[%o1] ! и я запиши в низа 34 006c 81C3E008 retl ! („add“ се изпълнява преди „retl“) 35 0070 92026001 add %o1,1,%o1 ! Обнови указателя MIPS LISTING putipstr.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър $5, 2 # низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 # байтовете точка, получен от IP-адрес (IPv4), подаден в регистър $4. 4 5 .ent putipstr 6 .global putipstr 7 putipstr: 8 0000 03E05025 MOVE $10,$31 # Съхрани lr, защото BAL ще го промени! 9 0004 240B0009 LI $11,9 # Подготви най-голямото едноцифрено 10 0008 240C0063 LI $12,99 # и най-голямото двуцифрено число за сравнение 11 000c 3C062E2E 34C62E00 DLA $6,'.' << 24 |'.' << 16 | '.' << 8 12 0014 7C873E03 L1: DEXT $7,$4,24,8 # Зареди следващ байт (от старши към младши) 13 0018 00042238 DSLL $4,$4,8 # Измести IP-адреса с 1 байт наляво 14 001c 0167082A 10200008 00000000 BLE $7,$11,L3 # Само единици? Запиши ги без нули пред тях 15 0028 0187082A 10200003 00000000 BLE $7,$12,L2 # Няма стотици? " " " " " " " 16 LI $8,100 # Получи и запиши цифрите на стотиците 17 0034 0411000B 24080064 BAL Digit 18 L2: LI $8,10 # Направи същото и с десетиците, 19 003c 04110009 2408000A BAL Digit 20 L3: LI $8,1 # и с единиците 21 0044 04110007 24080001 BAL Digit 22 004c 0006323A DSRL $6,$6,8 # Последен байт? 23 0050 A0A60000 SB $6,0($5) # (Запиши разделителя или терминатора в низа 24 DADDIU $5,$5,1 # и обнови адреса) 25 0054 14C0FFEF 64A50001 BNE $6,$0,L1 # Не, премини към обработка на следващия байт 26 005c 01400008 00000000 JR $10 # Да, върни управлението 27 28 0064 15000002 00E8001F 0007000D 00003812 Digit: DDIVU $7,$8 # Раздели байта на теглото на поредната цифра 29 0074 00004812 MFLO $9 # Частното е поредната цифра, 30 0078 00003810 MFHI $7 # а остатъкът - това са следващите цифри 31 007c 65290030 DADDIU $9,$9,'0' # Преобразувай цифрата в ASCII-код 32 0080 A0A90000 SB $9,0($5) # и я запиши в низа 33 DADDIU $5,$5,1 # Обнови адреса 34 0084 03E00008 64A50001 JR $31 35 008c 00000000 .end putipstr RISC-V LISTING putipstr.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър a1, 2 # низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 # байтовете точка, получен от IP-адрес (IPv4), подаден в регистър a0. 4 5 .global putipstr 6 putipstr: 7 0000 93089000 LI a7,9 # Подготви най-голямото едноцифрено 8 0004 93023006 LI t0,99 # и най-голямото двуцифрено число за сравнение 9 0008 37362E2E 1B0606E0 LA a2,'.' << 24 |'.' << 16 | '.' << 8 10 0010 9B568501 L1: SRLIW a3,a0,24 # Зареди следващ байт (от старши към младши) 11 0014 13158500 SLLI a0,a0,8 # Измести IP-адреса с 1 байт наляво 12 0018 63DCD800 BLE a3,a7,L3 # Само единици? Запиши ги без нули пред тях 13 001c 63D6D200 BLE a3,t0,L2 # Няма стотици? " " " " " " " 14 0020 13074006 LI a4,100 # Получи и запиши цифрите на стотиците 15 0024 6F088002 JAL a6,Digit 16 0028 1307A000 L2: LI a4,10 # Направи същото и с десетиците, 17 002c 6F080002 JAL a6,Digit 18 0030 13071000 L3: LI a4,1 # и с единиците 19 0034 6F088001 JAL a6,Digit 20 0038 13568600 SRLI a2,a2,8 # Последен байт? 21 003c 2380C500 SB a2,0(a1) # (Запиши разделителя или терминатора в низа 22 0040 93851500 ADDI a1,a1,1 # и обнови адреса) 23 0044 E31606FC BNEZ a2,L1 # Не, премини към обработка на следващия байт 24 0048 67800000 RET # Да, върни управлението 25 26 004c B3D7E602 Digit: DIVU a5,a3,a4 # Раздели байта на теглото на поредната цифра 27 0050 B3F6E602 REMU a3,a3,a4 # Частно = текущата цифра, остатък = следващите 28 0054 93870703 ADDI a5,a5,'0' # Преобразувай цифрата в ASCII-код 29 0058 2380F500 SB a5,0(a1) # и я запиши в низа 30 005c 93851500 ADDI a1,a1,1 # Обнови адреса 31 0060 67000800 JR a6 LOONGARCH64 GAS putipstr.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър $r5, 2 # низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 # байтовете точка, получен от IP-адрес (IPv4), подаден в регистър $r4. 4 5 .global putipstr 6 putipstr: 7 0000 2D001500 OR $r13,$r1,$r0 # Съхрани r1, защото BL ще го промени! 8 0004 0B248003 ORI $r11,$r0,9 # Подготви най-голямото едноцифрено 9 0008 0C8C8103 ORI $r12,$r0,99 # и най-голямото двуцифрено число за сравнение 10 000c 465C5C14 LU12I.W $r6,0x2E2E2 # Подготви 3 разделителя и 1 терминатор (0) 11 0010 C600B803 ORI $r6,$r6,0xE00 # 0x2E2E2E00 = '.' << 24 | '.' << 16 | '.' << 8 12 0014 8760DF00 L1: BSTRPICK.D $r7,$r4,31,24# Зареди следващ байт (от старши към младши) 13 0018 84204100 SLLI.D $r4,$r4,8 # Измести IP-адреса с 1 байт наляво 14 001c 67190064 BLE $r7,$r11,L3 # Само единици? Запиши ги без нули пред тях 15 0020 870D0064 BLE $r7,$r12,L2 # Няма стотици? " " " " " " " 16 0024 08908103 ORI $r8,$r0,100 # Получи и запиши цифрите на стотиците 17 0028 00280054 BL Digit 18 002c 08288003 L2: ORI $r8,$r0,10 # Направи същото и с десетиците, 19 0030 00200054 BL Digit 20 0034 08048003 L3: ORI $r8,$r0,1 # и с единиците 21 0038 00180054 BL Digit 22 003c C6204500 SRLI.D $r6,$r6,8 # Последен байт? 23 0040 A6000029 ST.B $r6,$r5,0 # (Запиши разделителя или терминатора в низа 24 0044 A504C002 ADDI.D $r5,$r5,1 # и обнови адреса) 25 0048 DFCCFF47 BNEZ $r6,L1 # Не, премини към обработка на следващия байт 26 004c A001004C JIRL $r0,$r13,0 # Да, върни управлението 27 28 0050 E9202300 Digit: DIV.DU $r9,$r7,$r8 # Раздели байта на теглото на поредната цифра 29 0054 E7A02300 MOD.DU $r7,$r7,$r8 # Частно = текущата цифра, остатък = следващите 30 0058 29C1C002 ADDI.D $r9,$r9,'0' # Преобразувай цифрата в ASCII-код 31 005c A9000029 ST.B $r9,$r5,0 # и я запиши в низа 32 0060 A504C002 ADDI.D $r5,$r5,1 # Обнови адреса 33 0064 2000004C JIRL $r0,$r1,0 # Да се напише подпрограма, която да записва от адрес, подаден в регистър $17, # низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между putipstr.o: file format ecoff-littlealpha # байтовете точка, получен от IP-адрес (IPv4), подаден в регистър $16. Disassembly of section .text: .ent putipstr .globl putipstr 0000000000000000 : putipstr: 0: 2e 2e 1f 25 ldah t7,11822(zero) bis $31,$26,$5 # Съхрани $26, защото „bsr“ ще го промени, 4: 10 80 7d a6 ldq a3,-32752(gp) bis $31,$16,$6 # както и регистрите за аргументи, защото ще 8: 07 04 f1 47 mov a1,t6 bis $31,$17,$7 # трябват за извикване подпрограмата за делене c: 05 04 fa 47 mov ra,t4 lda $19,REM # Адрес за остатъка 10: 00 2e 08 21 lda t7,11776(t7) ldah $8,0x2E2E($31) 14: 06 04 f0 47 mov a0,t5 lda $8,0x2E00($8) # $1 = '.' << 24 |'.' << 16 | '.' << 8 18: d0 70 c0 48 extbl t5,0x3,a0 L1: extbl $6,3,$16 # Зареди следващ байт (от старши към младши) 1c: 26 17 c1 48 sll t5,0x8,t5 sll $6,8,$6 # Измести IP-адреса с 1 байт наляво 20: b4 37 01 42 cmpule a0,0x9,a4 cmpule $16,9,$20 # Само единици? 24: 06 00 80 f6 bne a4,40 bne $20,L3 # Да, запиши ги без нули пред тях 28: b4 77 0c 42 cmpule a0,0x63,a4 cmpule $16,99,$20 # Не, няма стотици? 2c: 02 00 80 f6 bne a4,38 bne $20,L2 # Да, запиши ги без нули пред тях 30: 12 94 ec 47 mov 0x64,a2 bis $31,100,$18 # Не, получи и запиши цифрите на стотиците 34: 0a 00 40 d3 bsr ra,60 bsr Digit 38: 12 54 e1 47 mov 0xa,a2 L2: bis $31,10,$18 # Направи същото и с десетиците, 3c: 08 00 40 d3 bsr ra,60 bsr Digit 40: 12 34 e0 47 mov 0x1,a2 L3: bis $31,1,$18 # и с единиците 44: 06 00 40 d3 bsr ra,60 bsr Digit 48: 88 16 01 49 srl t7,0x8,t7 srl $8,8,$8 # Последен байт? 4c: 00 00 07 39 stb t7,0(t6) stb $8,0($7) # (Запиши разделителя или терминатора в низа 50: 07 34 e0 40 addq t6,0x1,t6 addq $7,1,$7 # и обнови адреса) 54: f0 ff 1f f5 bne t7,18 bne $8,L1 # Не, премини към обработка на следващия байт 58: 1a 04 bf 44 or t4,zero,ra bis $5,$31,$26 # Да, върни управлението 5c: 01 80 fa 6b ret zero,(ra),0x1 ret 60: 15 04 fa 47 mov ra,a5 Digit: bis $31,$26,$21 # Съхрани $26, защото „bsr“ ще го промени 64: 11 04 ff 47 clr a1 bis $31,$31,$17 # Старша дума на делимото (udiv128 променя $17) 68: 00 00 40 d3 bsr ra,6c bsr udiv128 # Раздели байта на теглото на поредната цифра 6c: 10 80 1d a6 ldq a0,-32752(gp) ldq $16,REM # Частно: поредната цифра, остатък: следващите 70: 14 14 06 40 addq v0,0x30,a4 74: 00 00 10 a6 ldq a0,0(a0) addq $0,48,$20 # Преобразувай цифрата в ASCII-код ('0' = 48) 78: 00 00 87 3a stb a4,0(t6) stb $20,0($7) # и я запиши в низа 7c: 1a 04 f5 47 mov a5,ra addq $7,1,$7 # Обнови адреса на текущия символ 80: 07 34 e0 40 addq t6,0x1,t6 bis $31,$21,$26 # Възстанови адреса на връщане 84: 01 80 fa 6b ret zero,(ra),0x1 ret # и върни управлението 88: 1f 04 ff 47 nop .data 8c: 00 00 fe 2f unop REM: .quad 0 .end putipstr GAS for MMIX putipstr.s page 1 1 % Да се напише подпрограма, която да записва от адрес, подаден в регистър $1, 2 % низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 % байтовете точка, получен от IP-адрес (IPv4), подаден в регистър $0. 4 5 .global putipstr 6 putipstr: 7 0000 C6020202 XOR $2,$2,$2 8 0004 F6010002 PUT rD,$2 % Нулирай старшата дума на делимото 9 0008 23020000 LDA $2,'.' << 24 |'.' << 16 | '.' << 8 10 000c 3B000020 SLU $0,$0,32 % Подравни IP-адреса най-вляво 11 0010 3F040038 L1: SRU $4,$0,56 % Зареди следващ байт (от старши към младши) 12 0014 3B000008 SLU $0,$0,8 % Измести IP-адреса с 1 байт наляво 13 0018 33030409 CMPU $3,$4,9 % Само единици? 14 001c 4C03000D BNP $3,L3 % Да, запиши ги без нули пред тях 15 0020 33030463 CMPU $3,$4,99 % Не, няма стотици? 16 0024 4C030006 BNP $3,L2 % Да, запиши ги без нули пред тях 17 0028 1F030464 DIVU $3,$4,100 % Не, раздели байта на теглото на цифрата им 18 002c FE040006 GET $4,rR % Частно: поредната цифра, остатък: следващите 19 0030 23030330 ADDU $3,$3,'0' % Преобразувай цифрата в ASCII-код 20 0034 A3030100 STBU $3,$1,0 % и я запиши в низа 21 0038 23010101 ADDU $1,$1,1 % Обнови адреса на текущия символ 22 003c 1F03040A L2: DIVU $3,$4,10 % Направи същото и с десетиците, 23 0040 FE040006 GET $4,rR 24 0044 23030330 ADDU $3,$3,'0' 25 0048 A3030100 STBU $3,$1,0 26 004c 23010101 ADDU $1,$1,1 27 0050 23040430 L3: ADDU $4,$4,'0' % и с единиците 28 0054 A3040100 STBU $4,$1,0 29 0058 23010101 ADDU $1,$1,1 30 005c 3F020208 SRU $2,$2,8 % Последен байт? 31 0060 A3020100 STBU $2,$1,0 % (Запиши разделителя или терминатора в низа 32 0064 23010101 ADDU $1,$1,1 % и обнови адреса) 33 0068 4B02FFEA BNZ $2,L1 % Не, премини към обработка на следващия байт 34 006c F8000000 POP 0,0 % Да, върни управлението HPPA64 LISTING putipstr.s page 1 1 ; Да се напише подпрограма, която да записва от адрес, подаден в регистър %R25, 2 ; низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 ; байтовете точка, получен от IP-адрес (IPv4), подаден в регистър %R26. 4 5 ZDELIM = '. << 24 | '. << 16 | '. << 8 6 .global putipstr 7 putipstr: 8 0000 081A0256 COPY %R26,%R22 ; Съхрани IP-адр. (R26 е ст.дума на делимото на 9 0004 08190255 COPY %R25,%R21 ; udiv128),адр.на низа (R25 е младшата му дума) 10 0008 0802025F COPY %R2,%R31 ; и адр. на връщане (R2 се използва от udiv128) 11 000c 22E00000 LDIL L%REM,%R23 12 0010 36F70000 LDO R%REM(%R23),%R23; R23: адрес на остатъка след изпълн.на udiv128 13 0014 2291D5C4 LDIL L%ZDELIM,%R20 ; R22: IP-адрес, R21: адрес на низа, R25: байт 14 0018 36940C00 LDO R%ZDELIM(%R20),%R20; Подготви 3 разделителя и 1 терминатор (0) 15 001c DAD908F8 L1: EXTRD,U %R22,39,8,%R25 ; Зареди следващ байт (от старши към младши) 16 0020 8F34A068 CMPIB,>> 10,%R25,L3 ; Само единици? Запиши ги направо, без водещи 0 17 0024 F2D60108 DEPD,Z %R22,55,24,%R22 ; Измести адр.с байт вляво (изп.се преди CMPIB) 18 0028 0800025A COPY %R0,%R26 ; Нулирай старшата дума на делимото на udiv128 19 002c E800A000 B,L udiv128,%R2 ; Раздели R25 на 100: R28 частно, *R23 остатък 20 0030 341800C8 LDI 100,%R24 ; Делител (изп. се преди B,L, делимото е в R25) 21 0034 87802010 CMPIB,= 0,%R28,L2 ; Само десетици и единици? Прескочи стотиците 22 0038 0EE010D9 LDD 0(%R23),%R25 ; Остатъкът ще бъде делимо (изп.се преди CMPIB) 23 003c D7861C9E DEPWI 3,27,2,%R28 ; Преобразувай цифрата на стотиците в ASCII-код 24 0040 0EBC1222 STB,MA %R28,1(%R21) ; Запиши ASCII-кода в низа, обновявайки адреса 25 0044 0800025A L2: COPY %R0,%R26 ; Пак нулирай променената ст. дума на делимото! 26 0048 E800A000 B,L udiv128,%R2 ; Получи десетиците и единиците по същия начин 27 004c 34180014 LDI 10,%R24 ; Делител за десетиците (изпълн. се преди B,L) 28 0050 0EE010D9 LDD 0(%R23),%R25 ; Остатъкът е цифрата на единиците, а частното 29 0054 D7861C9E DEPWI 3,27,2,%R28 ; – на десетиците. Преобразувай я в ASCII и я 30 0058 0EBC1222 STB,MA %R28,1(%R21) ; запиши в низа, обновявайки после и адреса му 31 005c D7261C9E L3: DEPI 3,27,2,%R25 ; Постъпи по същия начин 32 0060 0EB91222 STB,MA %R25,1(%R21) ; с цифрата на единиците 33 0064 D2800AF4 SHRPW %R0,%R20,8,%R20 ; Подготви следващ разделител или терминатор... 34 0068 8E803F5D CMPIB,<> 0,%R20,L1 ; (не е 0? Отиди на следващия; изп.се след STB) 35 006c 0EB41222 STB,MA %R20,1(%R21) ; ...и го запиши в низа, обновявайки и адреса 36 0070 EBE0D002 BVE,N (%R31) ; Адресът на връщане е бил съхранен в %R31 37 .data 38 0000 FFFFFFFF REM: .quad -1 38 FFFFFFFF UNDEFINED SYMBOLS udiv128 TILE-Gx GAS putipstr.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър r1, 2 # низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 # байтовете точка, получен от IP-адрес (IPv4), подаден в регистър r0. 4 5 .global putipstr 6 putipstr: 7 { MOVE r8,lr # Съхрани lr, защото „JAL“ ще го промени, 8 0000 C8FD07D1 04F83B28 MOVE r9,r0 } # както и регистрите за аргументи, защото ще 9 { MOVE r10,r1 # трябват за извикване подпрограмата за делене 10 0008 4AF007D1 E1070000 MOVELI r3,hw1_last(REM)}#Адрес за остатъка 11 { SHL16INSLI r3,r3,hw0(REM) 12 0010 C30000F0 E5777101 MOVELI r11,'.' << 8 | '.' } 13 0018 003048D1 65017039 SHL16INSLI r11,r11,'.' << 8 # r11 = '.' << 24 | '.' << 16 | '.' << 8 14 0020 40F26135 00306A28 L1: BFEXTU r0,r9,24,31 # Зареди следващ байт (от старши към младши) 15 { SHLI r9,r9,8 # Измести IP-адреса с 1 байт наляво 16 0028 49820860 02503018 CMPLTUI r4,r0,10 } # Само единици? 17 { BNEZ r4,L3 # Да, запиши ги без нули пред тях 18 0030 04406640 8200C017 CMPLTUI r4,r0,100 } # Не, няма стотици? 19 0038 00304851 8100C017 BNEZ r4,L2 # Да, запиши ги без нули пред тях 20 { MOVEI r2,100 # Не, получи и запиши цифрите на стотиците 21 0040 C24F16C0 03000020 JAL Digit } 22 L2: { MOVEI r2,10 # Направи същото и с десетиците, 23 0048 C2AF1040 03000020 JAL Digit } 24 L3: { MOVEI r2,1 # и с единиците 25 0050 C21F10C0 02000020 JAL Digit } 26 0058 003048D1 65410A30 SHRUI r11,r11,8 # Последен байт? (Запиши разделителя или 27 0060 003048D1 4059C818 ST1_ADD r10,r11,1 # терминатора в низа и обнови адреса) 28 0068 003048D1 7BF9BF17 BNEZT r11,L1 # Не, премини към обработка на следващия байт 29 0070 00304851 00716A28 JR r8 # Да, върни управлението 30 31 Digit:{ MOVE r12,lr # Съхрани lr, защото „JAL“ ще го промени 32 0078 CCFD07D1 E0FF3B28 MOVE r1,zero } # Старша дума на делимото (udiv128 променя r1) 33 0080 00304851 00000020 JAL udiv128 # Раздели байта на теглото на поредната цифра 34 { ADDI r5,r0,'0' # Преобразувай цифрата в ASCII-код ('0' = 48) 35 0088 05003304 0040069E LD r0,r3 } # Частно: поредната цифра, остатък: следващите 36 0090 003048D1 4029C818 ST1_ADD r10,r5,1 # Запиши цифрата в низа и обнови текущия адрес 37 0098 00304851 80716A28 JR r12 # Върни управлението 38 .data 39 0000 00000000 00000000 REM: .quad 0 UNDEFINED SYMBOLS udiv128 IA-64 GAS putipstr.s page 1 1 // Да се напише подпрограма, която да записва от адрес, подаден в регистър in1, 2 // низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 // байтовете точка, получен от IP-адрес (IPv4), подаден в регистър in0. 4 5 .global putipstr 6 putipstr: 7 ALLOC loc0=ar.pfs,2,3,3,0// Запази състоянието на извикващата функция 8 MOV loc1=rp // и адреса на връщане: „BR.CALL“ ще ги промени 9 MOVL loc2='.' << 24 | '.' << 16 | '.' << 8 10 0000 0010210A 80053002 00620000 00000400 MOV out2=in1 // Подготви адреса за запис от подпрограмата 11 L1: EXTR.U out0=in0,24,8 // Зареди следващ байт (от старши към младши) 12 0010 04000000 01002E00 00000080 04D07161 SHL in0=in0,8 // Измести IP-адреса с 1 байт наляво 13 0020 00380142 00210000 00020000 00000400 CMP.LTU p6,p7=99,out0 // Ако има стотици, 14 0030 01000000 01005082 810E2900 04BADD53 (p6) MOV out1=100 // получи и запиши тяхната цифра 15 (p6) BR.CALL.SPTK b6=Digit // („udiv128“ променя p6-p9!) 16 0040 0A308C4B 07B56122 03004800 00000400 (p7) CMP.GEU p7,p6=9,out0 // Провери за десетици, само ако няма стотици 17 (p6) MOV out1=10 // Иначе запиши цифрата на десетиците, дори да 18 0050 10000000 01000000 000200C3 80000050 (p6) BR.CALL.SPTK b6=Digit // е 0 19 0060 EA30244A 07B56152 00004800 00000400 MOV out1=1 20 BR.CALL.SPTK b6=Digit // Получи и запиши цифрата на единиците 21 0070 10000000 01000000 000200C3 60000050 SHR.U loc2=loc2,8 // Последен байт? 22 0080 10300500 00240000 000200C0 50000050 ST1 [out2]=loc2,1 // (Запиши разделителя или терминатора в низа 23 CMP.EQ p6,p7=loc2,r0 // и обнови адреса) 24 0090 02000000 01004082 906E2900 00000400 (p7) BR L1 // Не, премини към обработка на следващия байт 25 00a0 1008904E 80156020 010EF003 90FFFF48 MOV rp=loc1 // Да, възстанови адреса на връщане 26 MOV ar.pfs=loc0 // и състоянието на извикващата функция 27 BR.RET.SPTK rp // Върни управлението 28 //===> in0 = делимо, in1 = делител, in2 = адрес 29 00b0 00000000 01000018 05800300 2002AA00 Digit: ALLOC loc0=ar.pfs,3,2,4,0// Съхрани ar.pfs („BR.CALL“ ще го промени!) 30 MOV loc1=pr // и предикатите („udiv128“ ще промени някои!) 31 00c0 11000000 01000000 00020080 00008400 MOV out0=in0 // Младша дума на делимото 32 00d0 0018250A 80054002 006600A0 04000184 ADD out1=r0,r0 // Старша " " " " : udiv128 променя in1 33 MOV out2=in1 // Делител 34 MOVL out3=REM // Адрес за остатъка 35 00e0 00300100 00207002 84004200 00000400 BR.CALL.SPTK rp=udiv128 // Раздели байта на теглото на поредната цифра 36 LD8 in0=[out3] // Частно: поредната цифра, остатък: следващите 37 00f0 05000000 01000000 00000000 05000060 ADD r8='0',r8 // Преобразувай цифрата на частното в ASCII-код 38 0100 10000000 01000000 00020000 00000050 ST1 [in2]=r8,1 // и я запиши в низа с обновяване на адреса 39 0110 02000150 18108080 21004200 00000400 MOV pr=loc1 // Възстанови предикатите 40 MOV ar.pfs=loc0 // и състоянието на извикващата функция 41 0120 00082044 8015F027 C1BF0500 3002AA00 BR.RET.SPTK b6 // и върни управлението 42 0130 11000000 01000000 00020080 60008400 .data 43 0000 00000000 00000000 REM: .quad 0 UNDEFINED SYMBOLS udiv128 E2K GAS putipstr.s page 1 1 ! Да се напише подпрограма, която да записва от адрес, подаден в регистър r1, 2 ! низ тип ASCIIZ в десетичен формат без водещи нули и с разделител между 3 ! байтовете точка, получен от IP-адрес (IPv4), подаден в регистър r0. 4 5 .global putipstr 6 putipstr: 7 { setwd wsz=5,nfx=1 ! wsz = брой използвани регистри, nfx = неясно! 8 0000 12C00000 000000F0 00000000 B0000000 return %ctpr3 } ! Подготви връщането към извикващата функция 9 { ord 0,0x2E2E2E00,%r2! r2 = '.' << 24 | '.' << 16 | '.' << 8 10 0010 12400004 82D8C005 02000040 002E2E2E disp %ctpr1,L1 } ! и прехода към началото на цикъла 11 L1: { getfd %r0,8 << 6 | 24,%r4! Зареди следващ байт (от старши към младши) 12 0020 1200000C 84D4801F 80C88019 00001802 shld %r0,8,%r0 } ! Измести IP-адреса с 1 байт наляво 13 0030 11010004 60D48421 00000000 00006300 cmpbedb %r4,99,%pred0 ! Ако има стотици, 14 0040 11000180 83D48441 00006400 00006052 udivd %r4,100,%r3 ? ~%pred0 ! раздели байта на теглото на цифрата им 15 0050 11000104 83D48311 00003000 0000E004 addd %r3,'0',%r3 ? ~%pred0 ! преобразувай я в ASCII-код 16 { stb %r3,[%r1] ? ~%pred0 ! запиши я в низа 17 addd %r1,1,%r1 ? ~%pred0 ! и обнови адреса на текущия символ 18 0060 23000194 81C18111 83C08124 84D48445 00006400 6052E016 umodx %r4,100,%r4 ? ~%pred0 }! Остатъкът са десетиците и единиците 19 0078 11010104 60C98421 00000000 00006004 cmpbedb %r4,9,%pred0 ? %pred0 ! Ако няма стотици, провери за десетици 20 0088 11000180 83CA8441 00000000 00006052 udivd %r4,10,%r3 ? ~%pred0 ! Иначе запиши цифрата на десетиците по 21 0098 11000104 83D48311 00003000 0000E004 addd %r3,'0',%r3 ? ~%pred0 ! същия начин, дори да е 0 22 { stb %r3,[%r1] ? ~%pred0 23 addd %r1,1,%r1 ? ~%pred0 24 00a8 23000194 81C18111 83C08124 84CA8445 00000000 6052E016 umodx %r4,10,%r4 ? ~%pred0 } ! Остатъкът са единиците 25 00c0 11000004 84D48411 00000000 00003000 addd %r4,'0',%r4 ! Преобразувай и запиши по същия начин и тях 26 { stb %r4,[%r1] 27 addd %r1,1,%r1 28 00d0 1300001C 81C18111 82C8821B 84C08124 shrd %r2,8,%r2 } ! Подготви следващия разделител или терминатор 29 { stb %r2,[%r1] ! Запиши го в низа 30 addd %r1,1,%r1 ! и обнови адреса 31 00e0 1300001C 81C18111 40C08221 82C08124 cmpedb %r2,0,%pred0 } ! Последен байт? 32 00f0 01100000 600400C0 ct %ctpr1 ? ~%pred0! Не, премини към обработка на следващия байт 33 00f8 01100000 200C00C0 ct %ctpr3 ! Да, върни управлението S/390x LISTING getmacst.s page 1 1 # Да се напише подпрограма, която да връща в регистър 2 MAC-адреса, получен 2 # от низа тип ASCIIZ с начален адрес в същия регистър. Низът е в 16-ичен вид 3 # с разделител между байтовете препинателен знак, напр. 00-0C-76-1F-C5-EB 4 5 .global getmacst 6 getmacst: 7 0000 B9820044 XGR 4,4 # Започни начисто 8 0004 1733 L1: XR 3,3 # Нов текущ байт - започни натрупването от нулата 9 0006 E3102000 0090 L2: LLGC 1,0(2) # Зареди поредния символ 10 000c A72B0001 AGHI 2,1 # Обнови адреса 11 0010 EC140019 307C CGIJL 1,'0',L5# Разделител или терминатор - байтът е готов 12 0016 EC120007 397C CGIJH 1,'9',L3# Провери за буква или разделител 13 001c A71BFFD0 AGHI 1,-'0' # Цифра – преобразувай я от ASCII-код в тетрада битове 14 0020 A7F4000C J L4 15 0024 A51700DF L3: NILL 1,~('a-'A') & 0xFF#Преобразувай евентуална малка буква в главна 16 0028 EC14000D 417C CGIJL 1,'A',L5# Разделител - байтът е готов 17 002e EC12000A 467C CGIJH 1,'F',L5# " " " " " " " 18 0034 A71BFFC9 AGHI 1,10-'A'# Буква – преобразувай я от ASCII-код в тетрада битове 19 0038 89300004 L4: SLL 3,4 # Направи място за новата шестнадесетична цифра 20 003c 1E31 ALR 3,1 # и я добави към текущата стойност 21 003e A7F4FFE4 J L2 # Продължи със следващия символ от низа 22 0042 EB440008 000D L5: SLLG 4,4,8 # Измести текущия адрес в 4 с 1 байт наляво 23 0048 1643 OR 4,3 # Запиши текущия байт отдясно 24 004a 8411FFDD BRXH 1,1,L1 # Край на низа? Ако не, продължи със следващия байт 25 004e B9040024 LGR 2,4 # Да, върни адреса в 2 26 0052 07FE BR 14 AMD64 GAS getmacst.s page 1 1 # Да се напише подпрограма, която да връща в регистър RAX MAC-адреса, получен 2 # от низа тип ASCIIZ с начален адрес в регистър RDI. Низът е в 16-ичен вид с 3 # разделител между байтовете препинателен знак, напр. 00-0C-76-1F-C5-EB. 4 5 .intel_syntax noprefix 6 .global getmacst 7 getmacst: 8 0000 4889FE MOV RSI,RDI # LODSB работи с RSI 9 0003 4831D2 XOR RDX,RDX # Започни начисто 10 0006 B400 L1: MOV AH,0 # Нов текущ байт - започни натрупването от нулата 11 0008 AC L2: LODSB # Зареди поредния символ 12 0009 3C30 CMP AL,'0' # Цифра? 13 000b 7219 JB L4 # Не, разделител или терминатор е - байтът е готов 14 000d 3C39 CMP AL,'9' 15 000f 760C JBE L3 # Да, прескочи проверката за буква 16 0011 24DF AND AL,~('a'-'A')#Не, преобразувай евентуална малка буква в главна 17 0013 3C41 CMP AL,'A' # Главна буква? 18 0015 720F JB L4 # Не, разделител е - байтът е готов 19 0017 3C46 CMP AL,'F' 20 0019 770B JA L4 # Не, също 21 001b 2C07 SUB AL,'A'-10-'0'#Да, преобразувай я от ASCII-код в 2 стъпки 22 001d 2C30 L3: SUB AL,'0' # Преобразувай от ASCII-код 23 001f C0E404 SHL AH,4 # Направи място за новата тетрада 24 0022 08C4 OR AH,AL # и я добави 25 0024 EBE2 JMP L2 # Продължи със следващия символ от низа 26 0026 48C1E208 L4: SHL RDX,8 # Измести текущия адрес в RDX с байт наляво 27 002a 88E2 MOV DL,AH # Запиши текущия байт отдясно 28 002c 3C00 CMP AL,0 # Край на низа? 29 002e 75D6 JNZ L1 # Не, продължи със следващия байт 30 0030 4892 XCHG RAX,RDX # Върни адреса в RAX 31 0032 C3 RET AARCH64 GAS getmacst.s page 1 1 // Да се напише подпрограма, която да връща в регистър X0 MAC-адреса, получен 2 // от низа тип ASCIIZ с начален адрес в същия регистър. Низът е в 16-ичен вид 3 // с разделител между байтовете препинателен знак, например 00-0C-76-1F-C5-EB 4 5 .global getmacst 6 getmacst: 7 0000 E2031FAA MOV X2,XZR // Започни начисто 8 0004 E3031FAA L1: MOV X3,XZR // Нов текущ байт - започни натрупването от нулата 9 0008 01144038 L2: LDRB W1,[X0],#1//Зареди поредния символ 10 000c 3FC00071 CMP W1,#'0' // Цифра? 11 0010 A3010054 BLO L5 // Не, разделител или терминатор - байтът е готов 12 0014 3FE40071 CMP W1,#'9' 13 0018 68000054 BHI L3 // " " " " " " " " " " " " 14 001c 21C00051 SUB W1,W1,#'0'// Да, преобразувай от ASCII-код в тетрада битове 15 0020 07000014 B L4 16 0024 21781A12 L3: AND W1,W1,#~('a'-'A')//Преобразувай евентуална малка буква в главна 17 0028 3F040171 CMP W1,#'A' // Главна буква? 18 002c C3000054 BLO L5 // Не, разделител - байтът е готов 19 0030 3F180171 CMP W1,#'F' 20 0034 88000054 BHI L5 // " " " " " " " " 21 0038 21DC0051 SUB W1,W1,#'A'-10//Да, преобразувай от ASCII-код в тетрада битове 22 003c 2310030B L4: ADD W3,W1,W3,LSL #4//Добави я към умножената по 16 текуща стойност 23 0040 F2FFFF17 B L2 // Продължи със следващия символ от низа 24 0044 6220028B L5: ADD X2,X3,X2,LSL #8// Измести MAC-адреса вляво, запиши байта вдясно 25 0048 E1FDFF35 CBNZ W1,L1 // Край на низа? Продължи със следващия байт 26 004c E00302AA MOV X0,X2 // Върни MAC-адреса в X0 27 0050 C0035FD6 RET ARC GAS getmacst.s page 1 1 # Да се напише подпрограма, която да връща в регистър r0 MAC-адреса, получен 2 # от низа тип ASCIIZ с начален адрес в същия регистър. Низът е в 16-ичен вид 3 # с разделител между байтовете препинателен знак, например 00-0C-76-1F-C5-EB 4 5 .global getmacst 6 getmacst: 7 0000 00DA MOVL_S r2,0 # Започни начисто 8 0002 00DB L1: MOVL_S r3,0 # Нов текущ байт - започни натрупването от нулата 9 0004 0110 8104 L2: LDB.AB r1,[r0,1] # Зареди поредния символ 10 0008 2F09 1C0C BRLOL r1,'0',L5 # Разделител или терминатор - байтът е готов 11 000c 0B09 9D0E BRHSL r1,'9'+1,L3 # Провери за буква 12 0010 4259 010C SUBL r1,r1,'0' # Цифра – преобразувай от ASCII-код в тетрада битове 13 0014 0DF0 B_S L4 14 0016 5059 4101 L3: BCLRL r1,r1,5 # Преобразувай евентуална малка буква в главна 15 001a 1F09 0C0F 0000 4100 BRLOL r1,'A',L5 # Разделител - байтът е готов 16 0022 1709 0D0F 0000 4700 BRHSL r1,'F'+1,L5 # " " " " " " 17 002a 4259 C10D SUBL r1,r1,'A'-10# Главна буква – преобразувай от ASCII в тетрада 18 002e 605B 0301 L4: ASLL r3,r3,4 # Направи място за новата шестнадесетична цифра 19 0032 217B ADDL_S r3,r3,r1 # и я добави към текущата стойност 20 0034 E8F1 B_S L2 # Продължи със следващия символ от низа 21 0036 605A 0202 L5: ASLL r2,r2,8 # Измести текущия адрес в r2 с 1 байт наляво 22 003a 777A ORL_S r2,r2,r3 # Запиши текущия байт отдясно 23 003c E3E9 BRNEL_S r1,0,L1 # Разделител, а не терминатор - получи следващия байт 24 003e 4440 MOVL_S r0,r2 # Терминатор – върни адреса в r0 25 0040 E07E J_S [blink] PPC LISTING getmacst.s page 1 1 # Да се напише подпрограма, която да връща в регистър r3 MAC-адреса, получен 2 # от низа тип ASCIIZ с начален адрес в същия регистър. Низът е в 16-ичен вид 3 # с разделител между байтовете препинателен знак, напр. 00-0C-76-1F-C5-EB 4 5 .global getmacst 6 getmacst: 7 0000 3863FFFF addi r3,r3,-1# Компенсирай преинкрементната адресация 8 0004 38A00000 li r5,0 # Започни начисто 9 0008 38C00000 L1: li r6,0 # Нов текущ байт - започни натрупването от нулата 10 000c 8C830001 L2: lbzu r4,1(r3)# Зареди поредния символ 11 0010 28240030 cmpldi r4,'0 # Цифра? 12 0014 41800038 blt L5 # Не, разделител или терминатор е - байтът е готов 13 0018 28240039 cmpldi r4,'9 14 001c 4181000C bgt L3 # Не, провери за буква или разделител 15 0020 3884FFD0 addi r4,r4,-'0#Да, преобразувай от ASCII-код в тетрада битове 16 0024 4800001C b L4 17 0028 708400DF L3: andi. r4,r4,~('a-'A) & 0xFF# Преобразувай евентуална малка буква 18 002c 28240041 cmpldi r4,'A # в главна; главна буква? 19 0030 4180001C blt L5 # Не, разделител е - байтът е готов 20 0034 28240046 cmpldi r4,'F 21 0038 41810014 bgt L5 # Не, също 22 003c 3884FFC9 addi r4,r4,10-'A# Да, преобразувай от ASCII-код в тетрада битове 23 0040 78C626E4 L4: sldi r6,r6,4 # Направи място за новата шестнадесетична цифра 24 0044 7CC62214 add r6,r6,r4# и я добави към текущата стойност 25 0048 4BFFFFC4 b L2 # Продължи със следващия символ от низа 26 004c 78A545E4 L5: sldi r5,r5,8 # Измести текущия адрес в r5 с 1 байт наляво 27 0050 7CA53378 or r5,r5,r6# Запиши текущия байт отдясно 28 0054 28240000 cmpldi r4,0 # Край на низа? 29 0058 4082FFB0 bne L1 # Не, продължи със следващия байт 30 005c 7CA32B78 mr r3,r5 # Да, върни адреса в r3 31 0060 4E800020 blr SPARC GAS getmacst.s page 1 1 ! Да се напише подпрограма, която да връща в регистър %o0 MAC-адреса, получен 2 ! от низа тип ASCIIZ с начален адрес в същия регистър. Низът е в 16-ичен вид 3 ! с разделител между байтовете препинателен знак, напр. 00-0C-76-1F-C5-EB 4 5 .global getmacst 6 getmacst: 7 0000 92100000 clr %o1 ! Започни начисто 8 0004 96100000 L1: clr %o3 ! Нов текущ байт - започни натрупването от нулата 9 0008 D40A0000 L2: ldub [%o0],%o2! Зареди поредния символ 10 000c 90022001 add %o0,1,%o0! Обнови адреса 11 0010 80A2A030 cmp %o2,'0' ! Цифра? 12 0014 0A680010 bcs %xcc,L5 ! Не, разделител или тарминатор е - байтът е готов 13 0018 80A2A039 cmp %o2,'9' 14 001c 18680004 bgu %xcc,L3 ! Не, провери за буква или разделител 15 0020 01000000 nop 16 0024 10800009 ba L4 ! (изпълнява се след „sub“) 17 0028 9422A030 sub %o2,'0',%o2! Да, преобразувай от ASCII-код в тетрада битове 18 002c 940AA0DF L3: and %o2,~('a'-'A') & 0xFF,%o2! Преобразувай евентуална малка буква 19 0030 80A2A041 cmp %o2,'A' ! в главна; главна буква? 20 0034 0A680008 bcs %xcc,L5 ! Не, разделител е - байтът е готов 21 0038 80A2A046 cmp %o2,'F' 22 003c 18680006 bgu %xcc,L5 ! Не, също 23 0040 01000000 nop 24 0044 9422A037 sub %o2,'A'-10,%o2! Да, преобразувай от ASCII-код в тетрада битове 25 0048 972AF004 L4: sllx %o3,4,%o3! Направи място за новата шестнадесетична цифра 26 004c 10BFFFEF ba L2 !(продължи със следващия символ; изпълнява се след add) 27 0050 9602C00A add %o3,%o2,%o3! Добави я към текущата стойност 28 0054 932A7008 L5: sllx %o1,8,%o1! Измести текущия адрес в %o1 с 1 байт наляво 29 0058 0AFABFEB brnz %o2,L1 ! Ако има още байтове, продължи със следващия 30 005c 9212400B or %o1,%o3,%o1! (Запиши байт отдясно; изпълнява се преди „brnz“) 31 0060 81C3E008 retl 32 0064 90100009 mov %o1,%o0 ! Да, върни адреса в %o0:%o1; изпълнява се преди „retl“ MIPS LISTING getmacst.s page 1 1 # Да се напише подпрограма, която да връща в регистър $2 MAC-адреса, получен 2 # от низа тип ASCIIZ с начален адрес в регистър $4. Низът е в 16-ичен вид с 3 # разделител между байтовете препинателен знак, напр. 00-0C-76-1F-C5-EB 4 5 .ent getmacst 6 .global getmacst 7 getmacst: 8 0000 24020000 LI $2,0 # Започни начисто 9 0004 24060000 L1: LI $6,0 # Нов текущ байт - започни натрупването от нулата 10 0008 90880000 L2: LBU $8,0($4) # Зареди поредния символ 11 000c 64840001 DADDIU $4,$4,1 # Обнови адреса 12 0010 2D030030 SLTIU $3,$8,'0' # Цифра? 13 0014 14600011 00000000 BNE $3,$0,L5 # Не, разделител или терминатор е - байтът е готов 14 001c 2D03003A SLTIU $3,$8,'9'+1 15 0020 10600003 00000000 BEQ $3,$0,L3 # Не, провери за буква или разделител 16 DADDIU $8,$8,-'0' # Да, преобразувай от ASCII-код в тетрада битове 17 0028 10000009 6508FFD0 B L4 18 0030 310800DF L3: ANDI $8,$8,~('a'-'A') & 0xFF # Преобразувай евентуална малка буква 19 0034 2D030041 SLTIU $3,$8,'A' # в главна; главна буква? 20 0038 14600008 00000000 BNE $3,$0,L5 # Не, разделител е - байтът е готов 21 0040 2D030047 SLTIU $3,$8,'F'+1 22 0044 10600005 00000000 BEQ $3,$0,L5 # Не, също 23 004c 6508FFC9 DADDIU $8,$8,10-'A'# Да, преобразувай от ASCII-код в тетрада битове 24 0050 00063138 L4: DSLL $6,$6,4 # Направи място за новата шестнадесетична цифра 25 DADDU $6,$6,$8 # и я добави към текущата стойност 26 0054 1000FFEC 00C8302D B L2 # Продължи със следващия символ от низа 27 005c 00021238 L5: DSLL $2,$2,8 # Измести текущия адрес в $2 с 1 байт наляво 28 DINS $2,$6,0,8 # Запиши текущия байт отдясно 29 0060 1500FFE8 7CC23807 BNE $8,$0,L1 # Ако има още байтове, продължи със следващия байт 30 0068 03E00008 00000000 JR $31 # Ако не, върни адреса в $2 31 .end getmacst RISC-V LISTING getmacst.s page 1 1 # Да се напише подпрограма, която да връща в регистър a0 MAC-адреса, получен 2 # от низа тип ASCIIZ с начален адрес в същия регистър. Низът е в 16-ичен вид 3 # с разделител между байтовете препинателен знак, напр. 00-0C-76-1F-C5-EB 4 5 .global getmacst 6 getmacst: 7 0000 93060000 LI a3,0 # Започни начисто 8 0004 13060000 L1: LI a2,0 # Нов текущ байт - започни натрупването от нулата 9 0008 03470500 L2: LBU a4,0(a0) # Зареди поредния символ 10 000c 13051500 ADDI a0,a0,1 # Обнови адреса 11 0010 93370703 SLTIU a5,a4,'0' # Цифра? 12 0014 639C0702 BNEZ a5,L5 # Не, разделител или терминатор е - байтът е готов 13 0018 9337A703 SLTIU a5,a4,'9'+1 14 001c 63860700 BEQZ a5,L3 # Не, провери за буква или разделител 15 0020 130707FD ADDI a4,a4,-'0' # Да, преобразувай от ASCII-код в тетрада битове 16 0024 6F00C001 J L4 17 0028 1377F70D L3: ANDI a4,a4,~('a'-'A') & 0xFF # Преобразувай евентуална малка буква 18 002c 93371704 SLTIU a5,a4,'A' # в главна; главна буква? 19 0030 639E0700 BNEZ a5,L5 # Не, разделител е - байтът е готов 20 0034 93377704 SLTIU a5,a4,'F'+1 21 0038 638A0700 BEQZ a5,L5 # Не, също 22 003c 130797FC ADDI a4,a4,10-'A'# Да, преобразувай от ASCII-код в тетрада битове 23 0040 13164600 L4: SLLI a2,a2,4 # Направи място за новата шестнадесетична цифра 24 0044 3306E600 ADD a2,a2,a4 # и я добави към текущата стойност 25 0048 6FF01FFC J L2 # Продължи със следващия символ от низа 26 004c 93968600 L5: SLLI a3,a3,8 # Измести текущия адрес в a3 с 1 байт наляво 27 0050 B3E6C600 OR a3,a3,a2 # Запиши текущия байт отдясно 28 0054 E31807FA BNEZ a4,L1 # Ако има още байтове, продължи със следващия байт 29 0058 13850600 MV a0,a3 # Ако не, върни адреса в a0 30 005c 67800000 RET LOONGARCH64 GAS getmacst.s page 1 1 # Да се напише подпрограма, която да връща в регистър r4 MAC-адреса, получен 2 # от низа тип ASCIIZ с начален адрес в същия регистър. Низът е в 16-ичен вид 3 # с разделител между байтовете препинателен знак, напр. 00-0C-76-1F-C5-EB 4 5 .global getmacst 6 getmacst: 7 0000 0A001500 OR $r10,$r0,$r0 # Започни начисто 8 0004 06001500 L1: OR $r6,$r0,$r0 # Нов текущ байт - започни натрупването от нула 9 0008 8800002A L2: LD.BU $r8,$r4,0 # Зареди поредния символ 10 000c 8404C002 ADDI.D $r4,$r4,1 # Обнови адреса 11 0010 09C14002 SLTUI $r9,$r8,'0' # Цифра? 12 0014 20350044 BNEZ $r9,L5 # Не, разделител или терминатор: байтът е готов 13 0018 09E94002 SLTUI $r9,$r8,'9'+1 14 001c 200D0040 BEQZ $r9,L3 # Не, провери за буква или разделител 15 0020 0841FF02 ADDI.D $r8,$r8,-'0' # Да, преобразувай от ASCII-код в тетрада 16 0024 001C0050 B L4 17 0028 087D4303 L3: ANDI $r8,$r8,~('a'-'A') & 0xFF # Преобразувай евентуална малка буква 18 002c 09054102 SLTUI $r9,$r8,'A' # в главна; главна буква? 19 0030 20190044 BNEZ $r9,L5 # Не, разделител е - байтът е готов 20 0034 091D4102 SLTUI $r9,$r8,'F'+1 21 0038 20110040 BEQZ $r9,L5 # Не, също 22 003c 0825FF02 ADDI.D $r8,$r8,10-'A' # Да, преобразувай от ASCII-код в тетрада 23 0040 C6A02D00 L4: ALSL.D $r6,$r6,$r8,4 # Добави я към умножената по 16 текуща стойност 24 0044 FFC7FF53 B L2 # Продължи със следващия символ от низа 25 0048 4A214100 L5: SLLI.D $r10,$r10,8 # Измести текущия адрес в r10 с 1 байт наляво 26 004c 4A191500 OR $r10,$r10,$r6 # Запиши текущия байт отдясно 27 0050 1FB5FF47 BNEZ $r8,L1 # Ако има още байтове, продължи със следващия 28 0054 44011500 OR $r4,$r10,$r0 # Ако не, върни адреса в r4 29 0058 2000004C JIRL $r0,$r1,0 # Да се напише подпрограма, която да връща в регистър $0 MAC-адреса, получен # от низа тип ASCIIZ с начален адрес в регистър $16. Низът е в 16-ичен вид с getmacst.o: file format ecoff-littlealpha # разделител между байтовете препинателен знак, напр. 00-0C-76-1F-C5-EB Disassembly of section .text: .ent getmacst .globl getmacst 0000000000000000 : getmacst: 0: 00 04 ff 47 clr v0 bis $31,$31,$0 # Започни начисто 4: 01 04 ff 47 clr t0 L1: bis $31,$31,$1 # Нов текущ байт - започни натрупването от нулата 8: 00 00 50 28 ldbu t1,0(a0) L2: ldbu $2,0($16) # Зареди поредния символ c: a3 13 46 40 cmpult t1,0x30,t2 addq $16,1,$16 # Обнови адреса 10: 10 34 00 42 addq a0,0x1,a0 cmpult $2,0x30,$3 # Цифра? (0x30 = '0') 14: 0d 00 60 f4 bne t2,4c bne $3,L5 # Не, разделител или терминатор е - байтът е готов 18: a3 37 47 40 cmpule t1,0x39,t2 cmpule $2,0x39,$3 # 0x39 = '9' 1c: 02 00 60 e4 beq t2,28 beq $3,L3 # Не, провери за буква или разделител 20: 22 15 46 40 subq t1,0x30,t1 subq $2,0x30,$2 # Да, преобразувай от ASCII-код в тетрада битове 24: 06 00 e0 c3 br 40 br $31,L4 28: 02 f0 5b 44 and t1,0xdf,t1 L3: and $2,0xDF,$2 # Преобразувай евентуална малка буква: & ~('a'-'A') 2c: a3 33 48 40 cmpult t1,0x41,t2 cmpult $2,0x41,$3 # в главна; главна буква? (0x41 = 'A') 30: 06 00 60 f4 bne t2,4c bne $3,L5 # Не, разделител е - байтът е готов 34: a3 d7 48 40 cmpule t1,0x46,t2 cmpule $2,0x46,$3 # 0x46 = 'F' 38: 04 00 60 e4 beq t2,4c beq $3,L5 # Не, също 3c: 22 f5 46 40 subq t1,0x37,t1 subq $2,0x37,$2 # Да, преобразувай от ASCII-код (0x37 = 'A'-10) 40: 21 97 20 48 sll t0,0x4,t0 L4: sll $1,4,$1 # Направи място за новата шестнадесетична цифра 44: 01 04 22 40 addq t0,t1,t0 addq $1,$2,$1 # и я добави към текущата стойност 48: ef ff ff c3 br 8 br $31,L2 # Продължи със следващия символ от низа 4c: 20 17 01 48 sll v0,0x8,v0 L5: sll $0,8,$0 # Измести текущия адрес в $0 с 1 байт наляво 50: 00 04 01 44 or v0,t0,v0 bis $0,$1,$0 # Запиши текущия байт отдясно 54: eb ff 5f f4 bne t1,4 bne $2,L1 # Ако има още байтове, продължи със следващия байт 58: 01 80 fa 6b ret zero,(ra),0x1 ret # Ако не, върни адреса в $0 5c: 1f 04 ff 47 nop .end getmacst GAS for MMIX getmacst.s page 1 1 % Да се напише подпрограма, която да връща в регистър $0 MAC-адреса, получен 2 % от низа тип ASCIIZ с начален адрес в същия регистър. Низът е в 16-ичен вид 3 % с разделител между байтовете препинателен знак, напр. 00-0C-76-1F-C5-EB 4 5 .global getmacst 6 getmacst: 7 0000 C1040000 OR $4,$0,0 % Начален адрес 8 0004 C6000000 XOR $0,$0,$0 % Започни начисто 9 0008 C6010101 L1: XOR $1,$1,$1 % Нов текущ байт - започни натрупването от нулата 10 000c 83020400 L2: LDBU $2,$4,0 % Зареди поредния символ 11 0010 23040401 ADDU $4,$4,1 % Обнови адреса 12 0014 33030230 CMPU $3,$2,'0' % Цифра? 13 0018 4003000D BN $3,L5 % Не, разделител или терминатор е - байтът е готов 14 001c 33030239 CMPU $3,$2,'9' 15 0020 44030003 BP $3,L3 % Не, провери за буква или разделител 16 0024 27020230 SUBU $2,$2,'0' % Да, преобразувай от ASCII-код в тетрада битове 17 0028 F0000007 JMP L4 18 002c C90202DF L3: AND $2,$2,~('a'-'A') & 0xFF % Преобразувай евентуална малка буква 19 0030 33030241 CMPU $3,$2,'A' % в главна; главна буква? 20 0034 40030006 BN $3,L5 % Не, разделител е - байтът е готов 21 0038 33030246 CMPU $3,$2,'F' 22 003c 44030004 BP $3,L5 % Не, също 23 0040 27020237 SUBU $2,$2,'A'-10% Да, преобразувай от ASCII-код 24 0044 2E010102 L4: 16ADDU $1,$1,$2 % Вмъкни новата шестнадесетична цифра 25 0048 F1FFFFF1 JMP L2 % Продължи със следващия символ от низа 26 004c 3B000008 L5: SLU $0,$0,8 % Измести текущия адрес в $0 с 1 байт наляво 27 0050 C0000001 OR $0,$0,$1 % Запиши текущия байт отдясно 28 0054 4B02FFED BNZ $2,L1 % Ако има още байтове, продължи със следващия байт 29 0058 F8010000 POP 1,0 % Ако не, върни адреса в $0 HPPA64 LISTING getmacst.s page 1 1 ; Да се напише подпрограма, която да връща в регистър %R28 MAC-адреса, получен 2 ; от низа тип ASCIIZ с начален адрес в регистър %R26. Низът е в 16-ичен вид с 3 ; разделител между байтовете препинателен знак, например 00-0C-76-1F-C5-EB 4 5 .global getmacst 6 getmacst: 7 0000 341C0000 LDI 0,%R28 ; Започни начисто 8 0004 34170000 L1: LDI 0,%R23 ; Нов текущ байт - започни натрупването от нулата 9 0008 0F421039 L2: LDB,MA 1(%R26),%R25 ; Зареди поредния символ 10 000c 9320A060 CMPICLR,<<= '0,%R25,%R0; Разделител или терминатор? 11 0010 E800005A B,N L4 ; Да, байтът е готов 12 0014 93204072 CMPICLR,< '9,%R25,%R0; Не, цифра? 13 0018 E800002A B,N L3 ; Да, преобразувай я от ASCII 14 001c D7201CBF DEPWI 0,26,1,%R25 ; Не, преобразувай евентуална малка буква в главна 15 0020 9320A082 CMPICLR,<<= 'A,%R25,%R0 ; Разделител? 16 0024 E8000032 B,N L4 ; Да, байтът е готов 17 0028 9320908C CMPICLR,>>= 'F,%R25,%R0 ; Буква? 18 002c E8000022 B,N L4 ; Не, разделител – байтът е готов 19 0030 B73907F3 ADDI 10-'A+'0,%R25,%R25; Да, реобразувай буквата от ASCII в 2 стъпки 20 0034 B73907A1 L3: ADDI -'0,%R25,%R25; Цифра – преобразувай от ASCII в двоичнодесетичен 21 0038 08170A97 SHLADD,L %R23,2,%R0,%R23;Добави тетрадата към изместения с 4 б.тек.байт 22 003c E81F1F8D B L2 ; Продължи със следващия символ от низа 23 0040 0B370A97 SHLADD,L %R23,2,%R25,%R23; (2 пъти по 2 бита, второто се изп.преди „B“) 24 0044 F39C1108 L4: DEPD,Z %R28,55,56,%R28 ; Измести текущия адрес в %R28 с 1 байт наляво 25 0048 8F203F6D CMPIB,<> 0,%R25,L1 ; Ако последният символ не е терминатор, продължи 26 004c 0AFC025C OR %R28,%R23,%R28; Запиши текущия байт отдясно (изп.се до „CMPIB“) 27 0050 E840D002 BVE,N (%R2) ; Върни MAC-адреса в %R28 TILE-Gx GAS getmacst.s page 1 1 # Да се напише подпрограма, която да връща в регистър r0 MAC-адреса, получен 2 # от низа тип ASCIIZ с начален адрес в регистър r0. Низът е в 16-ичен вид с 3 # разделител между байтовете препинателен знак, напр. 00-0C-76-1F-C5-EB 4 5 .global getmacst 6 getmacst: 7 0000 003048D1 E0FF3B28 MOVE r1,zero # Започни начисто 8 0008 00304851 E1FF3B28 L1: MOVE r2,zero # Нов текущ байт - започни натрупването от нулата 9 0010 003048D1 01084018 L2: LD1U_ADD r3,r0,1 # Зареди поредния символ и обнови адреса 10 0018 00304851 62803118 CMPLTUI r4,r3,'0' # Цифра? 11 { BNEZ r4,L5 # Не, разделител или терминатор е - байтът е готов 12 0020 C4A06340 8500C017 CMPLTUI r4,r3,'9'+1 } 13 0028 00304851 81004014 BEQZ r4,L3 # Не, провери за буква или разделител 14 { ADDI r3,r3,-'0' # Да, преобразувай от ASCII-код в тетрада битове 15 0030 C3001D40 03000024 J L4 } 16 0038 003048D1 61F81E18 L3: ANDI r3,r3,~('a'-'A') # Преобразувай евентуална малка буква 17 0040 00304851 62083218 CMPLTUI r4,r3,'A' # в главна; главна буква? 18 { BNEZ r4,L5 # Не, разделител е - байтът е готов 19 0048 C47064C0 8200C017 CMPLTUI r4,r3,'F'+1 } 20 0050 00304851 82004014 BEQZ r4,L5 # Не, също 21 0058 003048D1 61480E18 ADDI r3,r3,10-'A'# Да, преобразувай от ASCII-код 22 0060 00304851 41200430 L4: SHLI r2,r2,4 # Направи място за новата шестнадесетична цифра 23 { ADD r2,r2,r3 # и я добави към текущата стойност 24 0068 82300CD0 FAFFFF27 J L2 } # Продължи със следващия символ от низа 25 0070 003048D1 20400430 L5: SHLI r1,r1,8 # Измести текущия адрес в r1 с 1 байт наляво 26 { OR r1,r1,r2 # Запиши текущия байт отдясно 27 0078 41200451 79F8BF17 BNEZT r3,L1 } # Ако има още байтове, продължи със следващия байт 28 { MOVE r0,r1 # Ако не, върни адреса в r0 29 0080 40F00751 E0766A28 JR lr } IA-64 GAS getmacst.s page 1 1 // Да се напише подпрограма, която да връща в регистър r8 MAC-адреса, получен 2 // от низа тип ASCIIZ с начален адрес в регистър in0. Низът е в 16-ичен вид с 3 // разделител между байтовете препинателен знак, напр. 00-0C-76-1F-C5-EB 4 5 .global getmacst 6 getmacst: 7 ALLOC loc0=ar.pfs,1,3,0,0 8 ADD r8=r0,r0 // Започни начисто 9 L1: ADD loc1=r0,r0 // Нов текущ байт - започни натрупването от нулата 10 0000 00081108 80058000 00004000 00000400 L2: LD1 loc2=[in0],1// Зареди поредния символ и обнови адреса 11 CMP.NE p8,p9=loc2,r0// Провери дали има още байтове 12 0010 00100100 00200000 00020000 00000400 CMP.LEU p6,p7='0',loc2// Цифра? 13 0020 0B180540 00149018 011070C0 F01A1DD4 (p6) CMP.GEU p6,p7='9',loc2 14 (p6) ADD loc2=-'0',loc2// Да, преобразувай от ASCII-код в тетрада битове 15 L3:(p6) SHLADD loc1=loc1,4,loc2 // Добави новата шестнадесетична цифра отдясно 16 0030 CB38E446 06B53182 8E7E4600 00000400 (p6) BR L2 // Продължи със следващия символ от низа 17 AND loc2=~('a'-'A'),loc2// Преобразувай евентуална малка буква 18 0040 D0108946 13200000 00020003 E0FFFF48 CMP.LEU p6,p7='A',loc2// в главна; главна буква? 19 (p6) CMP.GEU p6,p7='F',loc2 20 0050 0B187D47 2C226000 8E0E6A00 00000400 (p6) ADD loc2=-'A'+10,loc2// Да, преобразувай от ASCII-код в тетрада 21 (p6) BR L3 22 0060 CA381847 06B5314A 8E7E4600 00000400 SHL r8=r8,8 // Измести текущия адрес в r8 с 1 байт наляво 23 OR r8=r8,loc1 // Запиши текущия байт отдясно 24 0070 10000000 01000000 00020003 D0FFFF48 (p8) BR L1 // Ако има още байтове, продължи със следващия байт 25 0080 02000000 01008040 DCEE2900 81103980 BR.RET.SPTK rp // Върни адреса в r8 25 13000000 010002C0 FF7F2480 00008400 E2K GAS getmacst.s page 1 1 ! Да се напише подпрограма, която да връща в регистър r0 MAC-адреса, получен 2 ! от низа тип ASCIIZ с начален адрес в същия регистър. Низът е в 16-ичен вид 3 ! с разделител между байтовете препинателен знак, напр. 00-0C-76-1F-C5-EB 4 5 .global getmacst 6 getmacst: 7 { return %ctpr3 ! Подготви връщането към извикващата функция 8 0000 12400004 83838309 000000F0 00000000 xord %r3,%r3,%r3 }! Започни начисто 9 0010 01000004 81818109 L1: xord %r1,%r1,%r1 ! Нов текущ байт - започни натрупването от нулата 10 L2: { ldb [%r0],%r2 11 0018 1200000C 82C08064 80C18011 00000000 addd %r0,1,%r0 } ! Зареди поредния символ и обнови адреса 12 { cmpedb %r2,0,%pred1 ! Провери дали има още байтове 13 0028 1200000C 41C08221 82D48213 00003000 subd %r2,'0',%r2 }! Спекулативно преобразувай евентуална цифра с цел 14 0038 01010004 6082C021 cmpbedb 0,%r2,%pred0 ! намаляване на размера на операнд 1 до 5 бита 15 0040 11010104 60C98221 00000000 00006004 cmpbedb %r2,9,%pred0 ? %pred0! Цифра? 16 0050 11000104 82D48211 00003000 0000E004 addd %r2,'0',%r2 ? ~%pred0! Не, върни ASCII-кода в изходно положение 17 L3: { shl_addd %r1,4,%r2,%r1 ? %pred0! Добави новата 16-ична цифра отдясно 18 0060 22402108 81C48119 F7FFFF4F 0000820A 00000000 00006008 disp %ctpr1,L2 } ! Подготви прехода към началото на вътрешния цикъл 19 { ct %ctpr1 ? %pred0 ! Продължи със следващия символ от низа 20 0078 12100004 400400C0 82D48203 00002000 andnd %r2,97 - 65,%r2}! Преобразувай евентуална малка буква в главна 21 0088 11000004 82D48213 00000000 00003700 subd %r2,65 - 0xA,%r2! Спекулативно преобразувай евентуална буква 22 0098 01010004 6082CA21 cmpbedb 0xA,%r2,%pred0 ! (97 = 'a', 65 = 'A') 23 { cmpbedb %r2,0xF,%pred0 ? %pred0 ! Главна буква? Вече е преобразувана! 24 00a0 12400104 60CF8221 F8FFFF4F 00006004 disp %ctpr1,L3 } ! Подготви прехода към средата на вътрешния цикъл 25 00b0 01100000 400400C0 ct %ctpr1 ? %pred0! и премини към добавянето на тетрадата в байта 26 { shl_addd %r3,8,%r1,%r3!Разделител или терминатор – измести MAC-адреса с 27 00b8 12402008 83C88319 EBFFFF4F 0000810A disp %ctpr1,L1 } ! 1 байт вляво, запиши байта отдясно и подготви 28 00c8 01100000 610400C0 ct %ctpr1 ? ~%pred1! прехода към началото на външния цикъл. Ако 29 { ord %r3,0,%r0 ! има още байтове, продължи със следващия байт, 30 00d0 12100004 200C00C0 80C08305 00000000 ct %ctpr3 } ! иначе върни MAC-адреса в r0 S/390x LISTING putmacst.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър 3, 2 # низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 # получен от 48-битов MAC-адрес, подаден в регистър 2. 4 5 .global putmacst 6 putmacst: 7 0000 A759000C LGHI 5,12 # Инициализирай брояча на тетрадите 8 0004 EC023CBF 1455 L1: RISBG 0,2,60,0b10000000+63,20# Зареди тетрада (от старша към младша) 9 000a EB220004 000D SLLG 2,2,4 # Измести MAC-адреса с 1 тетрада наляво 10 0010 EC040005 0A7C CGIJL 0,0xA,L2 # Цифра - само добави ASCII-кода на 0 11 0016 A70B0007 AGHI 0,'A'-0xA-'0' # Буква – превърни с отчитане добавянето на '0' 12 001a A70B0030 L2: AGHI 0,'0' # Превърни (завърши преобразуването) в ASCII 13 001e 42003000 STC 0,0(3) # Запиши така получения ASCII-код в низа 14 0022 A73B0001 AGHI 3,1 # Обнови адреса 15 0026 A7510001 TMLL 5,1 # Четна тетрада (нечетна стойност на брояча)? 16 002a A7840006 JZ L3 # Не, продължи с младшата цифра на този байт 17 002e 922D3000 MVI 0(3),'-' # Да, запиши разделителя в низа 18 0032 A73B0001 AGHI 3,1 # Обнови адреса 19 0036 A757FFE7 L3: BRCTG 5,L1 # Премини към обработка на следващата тетрада 20 003a A73BFFFF AGHI 3,-1 # Замени шестото излишно тире с терминатор 0, 21 003e 42503000 STC 5,0(3) # връщайки се с 1 назад към неговия адрес 22 0042 07FE BR 14 AMD64 GAS putmacst.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър RSI, 2 # низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 # получен от MAC-адрес, подаден в регистър RDI. 4 5 .intel_syntax noprefix 6 .global putmacst 7 putmacst: 8 0000 480FACF8 30 SHRD RAX,RDI,48 # Запиши MAC-адреса в старшите 6 байта на RAX 9 0005 4889F7 MOV RDI,RSI # Начален адрес на низа 10 0008 B9AA0A00 00 MOV ECX,0xAAA # Инициализирай брояча на тетрадите 11 000d 48C1C004 L1: ROL RAX,4 # Измести MAC-адреса с 1 тетрада наляво 12 0011 240F AND AL,0xF # Изолирай най-старшата му тетрада в AL 13 0013 0430 ADD AL,'0' # Преобразувай в ASCII, приемайки я за цифра 14 0015 3C39 CMP AL,'9' # Буква? 15 0017 7602 JBE L2 # Не, цифра 16 0019 0407 ADD AL,'A'-'9'-1 # Да, увеличи ASCII-кода ѝ 17 001b AA L2: STOSB # Запиши така получения ASCII-код в низа 18 001c D1E9 SHR ECX,1 # Четна тетрада? 19 001e 73ED JNC L1 # Не, има още една 20 0020 B02D MOV AL,'-' # Да, подготви разделителя като следващ символ 21 0022 AA STOSB # и го запиши в низа 22 0023 75E8 JNZ L1 # Има и други байтове? Премини към следващия 23 0025 884FFF MOV BYTE PTR [RDI-1],CL# Замени шестото излишно тире с терминатор 0 24 0028 C3 RET AARCH64 GAS putmacst.s page 1 1 // Да се напише подпрограма, която да записва от адрес, подаден в регистър X1, 2 // низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 // получен от 48-битов MAC-адрес, подаден в регистър X0. 4 5 .global putmacst 6 putmacst: 7 0000 03020018 LDR W3,=0xAAA // Инициализирай брояча на тетрадите 8 0004 E2031F2A MOV W2,WZR // BFXIL не нулира битовете, които не заменя 9 0008 02BC6CB3 L1: BFXIL X2,X0,#44,#4 // Зареди нова тетрада (от старша към младша) 10 000c 00EC7CD3 LSL X0,X0,#4 // Измести MAC-адреса с 1 тетрада наляво 11 0010 5F280071 CMP W2,#0xA // Буква от A до F? 12 0014 44C00011 ADD W4,W2,#'0' // (преобразувай в ASCII-код, ако е цифра) 13 0018 43000054 BLO L2 // Не, прескочи 14 001c 841C0011 ADD W4,W4,#'A'-0xA-'0'// Да, допреобразувай я 15 0020 24140038 L2: STRB W4,[X1],#1 // Запиши така получения ASCII-код в низа 16 0024 637C0153 LSR W3,W3,#1 // Четна тетрада? 17 0028 63000037 TBNZ W3,#0,L3 // Не, прескочи 18 002c A4058052 MOV W4,#'-' // Да, подготви разделителя като следващ символ 19 0030 24140038 STRB W4,[X1],#1 // и го запиши в низа 20 0034 A3FEFF35 L3: CBNZ W3,L1 // Има и други байтове? Премини към следващия 21 0038 23F01F38 STRB W3,[X1,#-1] // Замени шестото излишно тире с терминатор 22 003c C0035FD6 RET // 0, връщайки се с 1 назад към неговия адрес 22 AA0A0000 ARC GAS putmacst.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър r1, 2 # низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 # получен от 48-битов MAC-адрес, подаден в регистър r0. 4 5 .global putmacst 6 putmacst: 7 0000 C743 0000 AA0A MOVL_S r3,0xAAA # Инициализирай брояча на тетрадите 8 0006 2D58 020F 0000 EC00 L1: XBFUL r2,r0,(4 - 1) << 6 | 44 # Зареди тетрада (от старша към младша) 9 000e 6058 0001 ASLL r0,r0,4 # Измести MAC-адреса с 1 тетрада наляво 10 0012 4C5A 8082 CMPL r2,0xA # Буква от A до F? 11 0016 C05A E60D ADDL.HS r2,r2,'A'-0xA # Да, преобразувай я в ASCII-код 12 001a C05A 250C ADDL.LO r2,r2,'0' # Не, цифра е - преобразувай я в ASCII-код 13 001e 0119 9200 STB.AB r2,[r1,1] # Запиши така получения ASCII-код в низа 14 0022 615B 4380 LSRL.F r3,r3,1 # Четна тетрада? 15 0026 71F7 BHS_S L1 # Не (няма пренос), премини към следващата 16 0028 2DDA MOVL_S r2,'-' # Да, подготви разделителя като следващ символ 17 002a 0119 9200 STB.AB r2,[r1,1] # и го запиши в низа 18 002e EDF5 BNE_S L1 # Има и други байтове? Премини към следващия 19 0030 FF19 C280 STB r3,[r1,-1] # Замени шестото излишно тире с терминатор 20 0034 E07E J_S [blink] # 0, връщайки се с 1 назад към неговия адрес PPC LISTING putmacst.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър r4, 2 # низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 # получен от 48-битов MAC-адрес, подаден в регистър r3. 4 5 .global putmacst 6 putmacst: 7 0000 3884FFFF addi r4,r4,-1 # Компенсирай преинкрементната адресация 8 0004 38C0000C li r6,12 # Инициализирай брояча на тетрадите 9 0008 7867A720 L1: rldicl r7,r3,20,60 # Зареди нова тетрада (от старша към младша) 10 000c 786326E4 sldi r3,r3,4 # Измести MAC-адреса с 1 тетрада наляво 11 0010 2827000A cmpldi r7,0xA # Буква от A до F? 12 0014 41800008 blt L2 # Не, цифра е - само добави ASCII-кода на 0 13 0018 38E70007 addi r7,r7,'A-0xA-'0 # Да, преобразувай с отчитане добавянето на '0' 14 001c 38E70030 L2: addi r7,r7,'0 # Превърни (завърши преобразуването) в ASCII 15 0020 9CE40001 stbu r7,1(r4) # Запиши така получения ASCII-код в низа 16 0024 70C50001 andi. r5,r6,1 # Четна тетрада (нечетна стойност на брояча)? 17 0028 4182000C beq L3 # Не, продължи с младшата цифра на този байт 18 002c 38E0002D li r7,'- # Да, подготви разделителя като следващ символ 19 0030 9CE40001 stbu r7,1(r4) # и го запиши в низа 20 0034 34C6FFFF L3: addic. r6,r6,-1 # Последна тетрада? 21 0038 4082FFD0 bne L1 # Не, премини към обработка на следващата 22 003c 98C40000 stb r6,0(r4) # Да, замени шестото излишно тире с терминатор 23 0040 4E800020 blr # (след преинкрементната адресация r5 сочи там) SPARC GAS putmacst.s page 1 1 ! Да се напише подпрограма, която да записва от адрес, подаден в регистър %o1, 2 ! низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 ! получен от 48-битов MAC-адрес, подаден в регистър %o0. 4 5 .global putmacst 6 putmacst: 7 0000 9610200C mov 12,%o3 ! Инициализирай брояча на тетрадите 8 0004 9532302C L1: srlx %o0,44,%o2 ! Зареди нова тетрада (от старша към младша) 9 0008 940AA00F and %o2,0xF,%o2 ! Изолирай я 10 000c 80A2A00A cmp %o2,0xA ! Буква от A до F? 11 0010 0A680003 bcs %xcc,L2 ! Не, цифра е - само добави ASCII-кода на 0 12 0014 912A3004 sllx %o0,4,%o0 ! (Измести MAC-адреса с 1 тетрада; преди „bcs“) 13 0018 9402A007 add %o2,'A'-0xA-'0',%o2! Да, превърни с отчитане добавянето на '0' 14 001c 9402A030 L2: add %o2,'0',%o2 ! Превърни (завърши преобразуването) в ASCII 15 0020 D42A4000 stb %o2,[%o1] ! Запиши така получения ASCII-код в низа 16 0024 92026001 add %o1,1,%o1 ! Обнови адреса 17 0028 808AE001 andcc %o3,1,%g0 ! Четна тетрада (нечетна стойност на брояча)? 18 002c 02680004 be %xcc,L3 ! Не, продължи с младшата цифра на този байт 19 0030 9410202D mov '-',%o2 ! Да, подготви разделителя като следващ символ 20 0034 D42A4000 stb %o2,[%o1] ! и го запиши в низа 21 0038 92026001 add %o1,1,%o1 ! Обнови адреса 22 003c 96A2E001 L3: subcc %o3,1,%o3 ! Последна тетрада? 23 0040 126FFFF1 bne %xcc,L1 ! Не, премини към обработка на следващата 24 0044 01000000 nop 25 0048 81C3E008 retl ! след „stb“ ! Да, замени шестото излишно тире с терминатор 26 004c D62A7FFF stb %o3,[%o1-1] ! 0, връщайки се с 1 назад към неговия адрес MIPS LISTING putmacst.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър $5, 2 # низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 # получен от 48-битов MAC-адрес, подаден в регистър $4. 4 5 .ent putmacst 6 .global putmacst 7 putmacst: 8 0000 2407000C LI $7,12 # Инициализирай брояча на тетрадите 9 0004 7C881B02 L1: DEXTU $8,$4,44,4 # Зареди нова тетрада (от старша към младша) 10 0008 00042138 DSLL $4,$4,4 # Измести MAC-адреса с 1 тетрада наляво 11 000c 2D06000A SLTIU $6,$8,0xA # Буква от A до F? 12 0010 14C00002 00000000 BNE $6,$0,L2 # Не, цифра е - само добави ASCII-кода на 0 13 0018 65080007 DADDIU $8,$8,'A'-0xA-'0'#Да, преобразувай с отчитане добавянето на '0' 14 001c 65080030 L2: DADDIU $8,$8,'0' # Превърни (завърши преобразуването) в ASCII 15 0020 A0A80000 SB $8,0($5) # Запиши така получения ASCII-код в низа 16 0024 64A50001 DADDIU $5,$5,1 # Обнови адреса 17 0028 30E60001 ANDI $6,$7,1 # Четна тетрада (нечетна стойност на брояча)? 18 002c 10C00004 00000000 BEQ $6,$0,L3 # Не, продължи с младшата цифра на този байт 19 0034 2408002D LI $8,'-' # Да, подготви разделителя като следващ символ 20 0038 A0A80000 SB $8,0($5) # и го запиши в низа 21 003c 64A50001 DADDIU $5,$5,1 # Обнови адреса 22 0040 64E7FFFF L3: DADDIU $7,$7,-1 # Последна тетрада? 23 0044 14E0FFEF 00000000 BNE $7,$0,L1 # Не, премини към обработка на следващата 24 SB $0,-1($5) # Да, замени шестото излишно тире с терминатор 25 004c 03E00008 A0A0FFFF JR $31 # 0, връщайки се с 1 назад към неговия адрес 26 0054 00000000 00000000 00000000 .end putmacst RISC-V LISTING putmacst.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър a1, 2 # низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 # получен от 48-битов MAC-адрес, подаден в регистър a0. 4 5 .global putmacst 6 putmacst: 7 0000 9306C000 LI a3,12 # Инициализирай брояча на тетрадите 8 0004 1357C502 L1: SRLI a4,a0,44 # Зареди нова тетрада (от старша към младша) 9 0008 1377F700 ANDI a4,a4,0xF # Изолирай я 10 000c 13154500 SLLI a0,a0,4 # Измести MAC-адреса с 1 тетрада наляво 11 0010 1336A700 SLTIU a2,a4,0xA # Буква от A до F? 12 0014 63140600 BNEZ a2,L2 # Не, цифра е - само добави ASCII-кода на 0 13 0018 13077700 ADDI a4,a4,'A'-0xA-'0'#Да, преобразувай с отчитане добавянето на '0' 14 001c 13070703 L2: ADDI a4,a4,'0' # Превърни (завърши преобразуването) в ASCII 15 0020 2380E500 SB a4,0(a1) # Запиши така получения ASCII-код в низа 16 0024 93851500 ADDI a1,a1,1 # Обнови адреса 17 0028 13F61600 ANDI a2,a3,1 # Четна тетрада (нечетна стойност на брояча)? 18 002c 63080600 BEQZ a2,L3 # Не, продължи с младшата цифра на този байт 19 0030 1307D002 LI a4,'-' # Да, подготви разделителя като следващ символ 20 0034 2380E500 SB a4,0(a1) # и го запиши в низа 21 0038 93851500 ADDI a1,a1,1 # Обнови адреса 22 003c 9386F6FF L3: ADDI a3,a3,-1 # Последна тетрада? 23 0040 E39206FC BNEZ a3,L1 # Не, премини към обработка на следващата 24 0044 A38F05FE SB x0,-1(a1) # Да, замени шестото излишно тире с терминатор 25 0048 67800000 RET # 0, връщайки се с 1 назад към неговия адрес LOONGARCH64 GAS putmacst.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър r5, 2 # низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 # получен от 48-битов MAC-адрес, подаден в регистър r4. 4 5 .global putmacst 6 putmacst: 7 0000 06308003 ORI $r6,$r0,12 # Инициализирай брояча на тетрадите 8 0004 87B0EF00 L1: BSTRPICK.D $r7,$r4,47,44# Зареди нова тетрада (от старша към младша) 9 0008 84104100 SLLI.D $r4,$r4,4 # Измести MAC-адреса с 1 тетрада наляво 10 000c E8284002 SLTUI $r8,$r7,0xA # Буква от A до F? 11 0010 00090044 BNEZ $r8,L2 # Не, цифра е - само добави ASCII-кода на 0 12 0014 E71CC002 ADDI.D $r7,$r7,'A'-0xA-'0' # Да, превърни с отчитане добавянето на '0' 13 0018 E7C0C002 L2: ADDI.D $r7,$r7,'0' # Превърни (завърши преобразуването) в ASCII 14 001c A7000029 ST.B $r7,$r5,0 # Запиши така получения ASCII-код в низа 15 0020 A504C002 ADDI.D $r5,$r5,1 # Обнови адреса 16 0024 C8044003 ANDI $r8,$r6,1 # Четна тетрада (нечетна стойност на брояча)? 17 0028 00110040 BEQZ $r8,L3 # Не, продължи с младшата цифра на този байт 18 002c 07B48003 ORI $r7,$r0,'-' # Да, подготви разделителя като следващ символ 19 0030 A7000029 ST.B $r7,$r5,0 # и го запиши в низа 20 0034 A504C002 ADDI.D $r5,$r5,1 # Обнови адреса 21 0038 C6FCFF02 L3: ADDI.D $r6,$r6,-1 # Последна тетрада? 22 003c DFC8FF47 BNEZ $r6,L1 # Не, премини към обработка на следващата 23 0040 A0FC3F29 ST.B $r0,$r5,-1 # Да, замени шестото излишно тире с терминатор 24 0044 2000004C JIRL $r0,$r1,0 # 0, връщайки се с 1 назад към неговия адрес # Да се напише подпрограма, която да записва от адрес, подаден в регистър $17, # низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, putmacst.o: file format ecoff-littlealpha # получен от 48-битов MAC-адрес, подаден в регистър $16. Disassembly of section .text: .ent putmacst .globl putmacst 0000000000000000 : putmacst: 0: 0c 00 1f 20 lda v0,12(zero) lda $0,12($31) # Инициализирай брояча на тетрадите 4: 30 17 02 4a sll a0,0x10,a0 sll $16,16,$16 # Най-старшата тетрада на MAC-адреса най-отляво 8: 81 96 07 4a srl a0,0x3c,t0 L1: srl $16,60,$1 # Зареди нова тетрада (от старша към младша) c: 30 97 00 4a sll a0,0x4,a0 sll $16,4,$16 # Измести MAC-адреса с 1 тетрада наляво 10: a2 53 21 40 cmpult t0,0xa,t1 cmpult $1,0xA,$2 # Буква от A до F? 14: 01 00 40 f4 bne t1,1c bne $2,L2 # Не, цифра е - само добави ASCII-кода на 0 18: 01 f4 20 40 addq t0,0x7,t0 addq $1,7,$1 #Да, отчети добавянето на '0' (7 = 'A'-0xA-'0') 1c: 01 14 26 40 addq t0,0x30,t0 L2: addq $1,0x30,$1 # Превърни (завърши превръщането) в ASCII: +'0' 20: 00 00 31 38 stb t0,0(a1) stb $1,0($17) # Запиши така получения ASCII-код в низа 24: 11 34 20 42 addq a1,0x1,a1 addq $17,1,$17 # Обнови адреса 28: 03 00 00 e0 blbc v0,38 blbc $0,L3 # Четна тетрада (нечетна стойност на брояча)? 2c: 2d 00 3f 20 lda t0,45(zero) lda $1,0x2D($31) # Да, подготви разделителя ('-') като следващ 30: 00 00 31 38 stb t0,0(a1) stb $1,0($17) # символ и го запиши в низа 34: 11 34 20 42 addq a1,0x1,a1 addq $17,1,$17 # Обнови адреса 38: 20 35 00 40 subq v0,0x1,v0 L3: subq $0,1,$0 # Последна тетрада? 3c: f2 ff 1f f4 bne v0,8 bne $0,L1 # Не, премини към обработка на следващата 40: ff ff f1 3b stb zero,-1(a1) stb $31,-1($17) # Да, замени шестото излишно тире с терминатор 44: 01 80 fa 6b ret zero,(ra),0x1 ret # 0, връщайки се с 1 назад към неговия адрес 48: 1f 04 ff 47 nop .end putmacst 4c: 00 00 fe 2f unop GAS for MMIX putmacst.s page 1 1 % Да се напише подпрограма, която да записва от адрес, подаден в регистър $1, 2 % низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 % получен от 48-битов MAC-адрес, подаден в регистър $0. 4 5 .global putmacst 6 putmacst: 7 0000 E303000C SETL $3,12 % Инициализирай брояча на тетрадите 8 0004 3B000010 SLU $0,$0,16 % Най-старшата тетрада на MAC-адреса най-отляво 9 0008 3F04003C L1: SRU $4,$0,60 % Зареди нова тетрада (от старша към младша) 10 000c 3B000004 SLU $0,$0,4 % Измести MAC-адреса с 1 тетрада наляво 11 0010 3302040A CMPU $2,$4,0xA % Буква от A до F? 12 0014 40020002 BN $2,L2 % Не, цифра е - само добави ASCII-кода на 0 13 0018 23040407 ADDU $4,$4,'A'-0xA-'0'%Да, отчети добавянето на '0' 14 001c 23040430 L2: ADDU $4,$4,'0' % Превърни (завърши превръщането) в ASCII 15 0020 A3040100 STBU $4,$1,0 % Запиши така получения ASCII-код в низа 16 0024 23010101 ADDU $1,$1,1 % Обнови адреса 17 0028 4E030004 BEV $3,L3 % Четна тетрада (нечетна стойност на брояча)? 18 002c E304002D SETL $4,'-' % Да, подготви разделителя ('-') като следващ 19 0030 A3040100 STBU $4,$1,0 % символ и го запиши в низа 20 0034 23010101 ADDU $1,$1,1 % Обнови адреса 21 0038 27030301 L3: SUBU $3,$3,1 % Последна тетрада? 22 003c 4B03FFF3 BNZ $3,L1 % Не, премини към обработка на следващата 23 0040 27010101 SUBU $1,$1,1 % Да, върни указателя с 1 (отместването е ≥ 0) 24 0044 A3030100 STBU $3,$1,0 % Замени шестото излишно тире с терминатор 25 0048 F8000000 POP 0,0 % 0, връщайки се с 1 назад към неговия адрес HPPA64 LISTING putmacst.s page 1 1 ; Да се напише подпрограма, която да записва от адрес, подаден в регистър %R25, 2 ; низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 ; получен от 48-битов MAC-адрес, подаден в регистър %R26. 4 5 .global putmacst 6 putmacst: ; %R23 = брояч на тетрадите, %R22 = тетрада 7 0000 3418005A LDI '-,%R24 ; Подготви разделителя между байтовете 8 0004 34170018 LDI 12,%R23 ; Инициализирай брояча на тетрадите 9 0008 DB56027C L1: EXTRD,U %R26,19,4,%R22 ; Зареди нова тетрада (от старша към младша) 10 000c F35A1084 DEPD,Z %R26,59,60,%R26 ; Измести MAC-адреса с 1 тетрада наляво 11 0010 92C07014 CMPICLR,> 10,%R22,%R0 ; Цифра ли е тетрадата? 12 0014 B6D6000E ADDI 'A-'0-10,%R22,%R22; Не, буква – преобразувай в ASCII в 2 стъпки 13 0018 B6D60060 ADDI '0,%R22,%R22 ; Да, – превърни в ASCII (II стъпка за букви) 14 001c 0F361222 STB,MA %R22,1(%R25) ; Запиши така получения ASCII-код в низа 15 0020 0AF7F240 OR,EV %R23,%R23,%R0 ; Нечетна тетрада (четна стойност на брояча)? 16 0024 0F381222 STB,MA %R24,1(%R25) ; Не, запиши тирето като следващ символ в низа 17 0028 AEFF3FB5 ADDIB,<> -1,%R23,L1 ; Да, премини към следващата тетрада 18 002c 08000240 NOP 19 0030 E840D000 BVE (%R2) ; Замени шестото излишно тире с терминатор 0, 20 0034 0F37323F STB,MB %R23,-1(%R25) ; връщайки се с 1 назад към неговия адрес TILE-Gx GAS putmacst.s page 1 1 # Да се напише подпрограма, която да записва от адрес, подаден в регистър r1, 2 # низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 # получен от 48-битов MAC-адрес, подаден в регистър r0. 4 5 .global putmacst 6 putmacst: 7 0000 00304851 E1670818 MOVEI r2,12 # Инициализирай брояча на тетрадите 8 0008 03F0B235 00306A28 L1: BFEXTU r3,r0,44,47 # Зареди нова тетрада (от старша към младша) 9 { SHLI r0,r0,4 # Измести MAC-адреса с 1 тетрада наляво 10 0010 00400860 62503018 CMPLTUI r4,r3,0xA } # Буква от A до F? 11 0018 00304851 81008017 BNEZT r4,L2 # Не, цифра е - само добави ASCII-кода на 0 12 0020 003048D1 61380818 ADDI r3,r3,'A'-0xA-'0'#Да, отчети добавянето на '0' 13 0028 003048D1 61800918 L2: ADDI r3,r3,'0' # Превърни (завърши превръщането) в ASCII-код 14 0030 003048D1 2018C818 ST1_ADD r1,r3,1 # Запиши този ASCII-код в низа и обнови адреса 15 { BLBC r2,L3 # Четна тетрада (нечетна стойност на брояча)? 16 0038 C3DF1240 4100C015 MOVEI r3,'-' } # Да, подготви разделителя като следващ символ 17 0040 003048D1 2018C818 ST1_ADD r1,r3,1 # запиши го в низа и обнови адреса 18 0048 00304851 41F80F18 L3: ADDI r2,r2,-1 # Последна тетрада? 19 0050 003048D1 5BF8BF17 BNEZT r2,L1 # Не, премини към обработка на следващата 20 0058 003048D1 20F80F18 ADDI r1,r1,-1 # Да, замени шестото излишно тире с терминатор 21 { ST1 r1,zero # 0, връщайки се с 1 назад към неговия адрес 22 0060 00301C30 E06EFEDD JR lr } IA-64 GAS putmacst.s page 1 1 // Да се напише подпрограма, която да записва от адрес, подаден в регистър in1, 2 // низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 // получен от 48-битов MAC-адрес, подаден в регистър in0. 4 5 .global putmacst 6 putmacst: 7 ALLOC loc3=ar.pfs,2,4,0,0 8 MOV loc2=ar.lc // Съхрани старата стойност на брояча на цикли 9 MOV ar.lc=12-1 // Инициализирай брояча на тетрадите 10 0000 0028190C 80054002 04650000 B0082A00 L1: EXTR.U loc1=in0,44,4 // Зареди нова тетрада (от старша към младша) 11 SHL in0=in0,4 // Измести MAC-адреса с 1 тетрада наляво 12 CMP.LEU p6,p7=0xA,loc1 // Буква от A до F? 13 0010 01000000 010030C2 82062900 04DAED53 (p6) ADD loc1='A'-0xA,loc1 // Да, преобразувай в ASCII 14 (p7) ADD loc1='0',loc1 // Не, цифра: " " " " 15 0020 0B302446 07B531BA 8D00C263 041B0184 ST1 [in1]=loc1,1 // Запиши този ASCII-код в низа и обнови адреса 16 MOV loc0=ar.lc // Прехвърли брояча в регистър за обща употреба 17 TBIT.Z p6,p7=loc0,0 // Четна тетрада (четна стойност на брояча)? 18 0030 03088C42 80152002 046500C0 00101D50 (p6) MOV loc1='-' // Да, подготви разделителя като следващ 19 (p6) ST1 [in1]=loc1,1 // символ, запиши го в низа и обнови адреса 20 BR.CLOOP.SPTK L1 // Премини към обработка на следващата тетрада 21 0040 CA18B500 00A41118 85002B00 00000400 SUB in1=in1,r0,1 // Замени шестото излишно тире с терминатор 0, 22 ST1 [in1]=r0 // връщайки се с 1 назад към неговия адрес 23 0050 11000000 01000000 000200A0 C0FFFF48 MOV ar.lc=loc2 // Възстанови стойността на брояча на цикли 24 0060 0A088500 04200000 84002300 400AAA00 BR.RET.SPTK rp 24 11000000 01000000 00020080 00008400 E2K GAS putmacst.s page 1 1 ! Да се напише подпрограма, която да записва от адрес, подаден в регистър r1, 2 ! низ тип ASCIIZ в шестнадесетичен формат с разделител между байтовете тире, 3 ! получен от 48-битов MAC-адрес, подаден в регистър r0. 4 5 .global putmacst 6 putmacst: 7 0000 01400000 000000F0 return %ctpr3 ! Подготви връщането към извикващата функция 8 { disp %ctpr1,L1 ! и прехода към началото на цикъла 9 0008 12400004 82CCC005 02000040 00000000 ord 0,12,%r2 } ! Инициализирай брояча на тетрадите 10 L1: { getfd %r0,4 << 6 | 44,%r3! Зареди нова тетрада (от старша към младша) 11 0018 1200000C 83D4801F 80C48019 00002C01 shld %r0,4,%r0 } ! Измести MAC-адреса с 1 тетрада наляво 12 0028 01010004 6083CA21 cmpbedb 0xA,%r3,%pred0 ! Буква от A до F? 13 { addd %r3,65 - 0xA,%r3 ? %pred0! Да, преобразувай в ASCII (65 = 'A') 14 0030 2200010C 83D48311 83D08311 00000000 30003700 0000600D addd %r3,'0',%r3 ? ~%pred0 } ! Не, цифра: " " " 15 { stb %r3,[%r1] ! Запиши този ASCII-код в низа 16 addd %r1,1,%r1 ! и обнови адреса 17 0048 1300001C 81C18111 40C18223 83C08124 cmpandedb %r2,1,%pred0 }! Четна тетрада (нечетна стойност на брояча)? 18 0058 11000104 83D4C005 00002D00 0000E004 ord 0,0x2D,%r3 ? ~%pred0! Да, подготви разделителя (0x2D = '-') 19 { stb %r3,[%r1] ? ~%pred0! като следващ символ, запиши го в низа 20 addd %r1,1,%r1 ? ~%pred0! и обнови адреса 21 subd %r2,1,%r2 ! Преброй тетрадата 22 0068 2400013C 81C18111 82C18213 83C08124 60C18221 0000E016 cmpbedb %r2,1,%pred0 } ! Има ли и други тетради? 23 0080 01100000 600400C0 ct %ctpr1 ? ~%pred0! Да, премини към обработка на следващата 24 { stb %r2,[%r1,-1] ! Не, замени шестото излишно тире с терминатор 25 0088 12100010 200C00C0 82D48124 0000FFFF ct %ctpr3 } ! 0, връщайки се с 1 назад към неговия адрес S/390x LISTING udiv128.s page 1 1 # Да се напише подпрограма, която да връща в регистър 2 частното, а на адрес, 2 # подаден в регистър 4, да записва остатъка от деленето на числото, чийто адрес 3 # ѝ е подаден в регистър 2, на числото в регистър 3. 4 5 .global udiv128 6 udiv128: 7 0000 EB012000 0004 LMG 0,1,0(2) # Зареди делимото в регистри 8 0006 B9870003 DLGR 0,3 # Рег. 1 = частно, рег. 0 = остатък 9 000a E3004000 0024 STG 0,0(4) # Запиши остатъка на посочения адрес 10 0010 B9040021 LGR 2,1 # Върни частното в рег. 2 11 0014 07FE0707 BR 14 AMD64 GAS udiv128.s page 1 1 # Да се напише подпрограма, която да връща в регистър RAX частното, а на адрес, 2 # подаден в RCX, да записва остатъка от деленето на числото в регистри RSI:RDI 3 # на числото в регистър RDX. 4 5 .intel_syntax noprefix 6 .global udiv128 7 udiv128: 8 0000 4897 XCHG RAX,RDI # RSI:RAX = делимо 9 0002 4887F2 XCHG RDX,RSI # RDX:RAX = делимо, RSI = делител 10 0005 48F7F6 DIV RSI # В x64 делимото е двойно по-дълго от делителя 11 0008 488911 MOV [RCX],RDX # Запиши остатъка 12 000b C3 RET # Върни частното в RAX AARCH64 GAS udiv128.s page 1 1 // Да се напише подпрограма, която да връща в регистър X0 частното, а на адрес, 2 // подаден в регистър X3, да записва остатъка от деленето на числото в регистри 3 // X1:X0 на числото в регистър X2. 4 5 .global udiv128 // http://codereview.stackexchange.com/questions/67962 6 udiv128: //Не може ADDS W4,WZR,#65: R31 тук е SP, не ZR 7 0000 24088052 MOV W4,#65 //Брч, няма нужда от отделни q и r (r = a_hi;) 8 0004 84001F2B ADDS W4,W4,WZR // C = 0 ______ q = a_lo<<1; carry = a_lo>>63; 9 0008 05000014 B L2 //______/ temp = r >> 63; r = r << 1 | 10 000c 210001BA L1: ADCS X1,X1,X1 // carry; carry = temp; 11 0010 223042FA CCMP X1,X2,#2,CC //Ако C==1,C=1 if (!carry) { 12 0014 43000054 BLO L2 // C == 0 if (r < b) goto shift; 13 0018 210002CB SUB X1,X1,X2 // C == 1 (carry++;) } r -= b; 14 001c 000000BA L2: ADCS X0,X0,X0 // shift: temp = q >> 63; q = 15 0020 84040051 SUB W4,W4,#1 //Още итерации? q << 1 | carry; carry = temp; 16 0024 44FFFF35 CBNZ W4,L1 //Да, продължи 17 0028 610000F9 STR X1,[X3] // *rem = r; 18 002c C0035FD6 RET // return q; //Възстанови и върни q в X0 ARC GAS udiv128.s page 1 1 # Да се напише подпрограма, която да връща в регистър r0 частното, а на адрес, 2 # подаден в регистър r3, да записва остатъка от деленето на числото в регистри 3 # r1:r0 на числото в регистър r2. 4 5 .global udiv128 # http://codereview.stackexchange.com/questions/67962 6 udiv128: 7 0000 C744 0000 4000 MOVL_S r4,64 #Брч __q = a_lo << 1; carry = a_lo >> 63; 8 0006 6058 4080 ASLL.F r0,r0,1 #___/ (r = a_hi;)//няма нужда от отделни q и r 9 000a 0159 4180 L1: ADCL.F r1,r1,r1 # temp = r>>63; r = r<<1 | carry; 10 000e 86F7 BLO_S L2 # carry = temp; if (!carry) { 11 0010 0B09 8C00 BRLOL r1,r2,L3 # if (r < b) goto shift; 12 0014 4E5B 3E80 RSUBL.F 0,r3,0 #______________ carry++; } r -= b; 13 0018 4379 L2: SUBL_S r1,r1,r2 #____/ shift: _temp = q >> 63; q = 14 001a 0158 0080 L3: ADCL.F r0,r0,r0 #_____________/_q << 1 | carry; carry = temp; 15 001e 8C24 FF0D DBNZ r4,L1 #Нова итерация 16 0022 001B 4700 STL r1,[r3] # *rem = r; 17 0026 E07E J_S [blink] # return q; //Върни q в r0 PPC LISTING udiv128.s page 1 1 # Да се напише подпрограма, която да връща в регистър r3 частното, а на адрес, 2 # подаден в регистър r6, да записва остатъка от деленето на числото в регистри 3 # r3:r4 на числото в регистър r5. 4 5 .global udiv128 # http://codereview.stackexchange.com/questions/67962 6 udiv128: 7 0000 39000000 li r8,0 # Ще потрябва за проверка на преноса 8 0004 34E80041 addic. r7,r8,65#CA=0, 65 итерации 9 0008 7CE903A6 mtctr r7 # _q = a_lo << 1; carry = a_lo >> 63; 10 000c 48000020 b L3 #_/(r = a_hi;)// няма нужда от отделни q и r 11 0010 7C631914 L1: adde r3,r3,r3# temp = r >> 63; r = r<<1 | carry; carry = temp; 12 0014 7CE801D5 addme. r7,r8 #CA-1=? (запази CA) 13 0018 41820010 beq L2 # if (!carry) { 14 001c 7C232840 cmpld r3,r5 # if (r < b) 15 0020 7CE51810 subfc r7,r5,r3#обн.CA 16 0024 41800008 blt L3 # goto shift; 17 0028 7C651850 L2: subf r3,r5,r3#CA=1 (carry++;) } r -= b; 18 002c 7C842114 L3: adde r4,r4,r4#shift: temp = q >> 63; q = q<<1 | carry; carry = temp; 19 0030 4200FFE0 bdnz L1 # Следваща итерация 20 0034 F8660000 std r3,0(r6)# *rem = r; 21 0038 7C832378 mr r3,r4 # return q; 22 003c 4E800020 blr SPARC GAS udiv128.s page 1 1 ! Да се напише подпрограма, която да връща в регистър %o0 частното, а на адрес, 2 ! подаден в регистър %o3, да записва остатъка от деленето на числото в регистри 3 ! %o0:%o1 на числото в регистър %o2. 4 5 .global udiv128 ! http://codereview.stackexchange.com/questions/67962 6 udiv128: ! q = a_lo<<1;(r = a_hi;)//няма нужда от отделни q, r 7 0000 9B32703F srlx %o1,63,%o5!/carry = a_lo >> 63; 8 0004 932A7001 sllx %o1,1,%o1!/ 9 0008 98102040 mov 64,%o4 !брч 10 000c 8332303F L1: srlx %o0,63,%g1! temp = r >> 63; 11 0010 912A3001 sllx %o0,1,%o0! r = r << 1 12 0014 9012000D or %o0,%o5,%o0! | carry; 13 0018 9A100001 mov %g1,%o5 ! carry = temp; 14 001c 0ACB4005 brnz %o5,L2 ! if (carry == 0) { 15 0020 80A2000A cmp %o0,%o2 ! if (r < b) // изп. се преди „brnz“! 16 0024 0A680004 bcs %xcc,L3 ! goto shift; 17 0028 01000000 nop 18 002c 9A036001 inc %o5 ! carry++; 19 0030 9022000A L2: sub %o0,%o2,%o0! } r -= b; 20 0034 8332703F L3: srlx %o1,63,%g1!shift:temp = q >> 63; 21 0038 932A7001 sllx %o1,1,%o1! q = q << 1 22 003c 9212400D or %o1,%o5,%o1! | carry; 23 0040 98A32001 deccc %o4 !Следваща 24 0044 126FFFF2 bne %xcc,L1 !итерация 25 0048 9A100001 mov %g1,%o5 ! carry = temp; // изпълнява се преди „bne“! 26 004c D072C000 stx %o0,[%o3]! *rem = r; 27 0050 81C3E008 retl 28 0054 90100009 mov %o1,%o0 ! return q; // изпълнява се преди „retl“! MIPS LISTING udiv128.s page 1 1 # Да се напише подпрограма, която да връща в регистър $2 частното, а на адрес, 2 # подаден в регистър $7, да записва остатъка от деленето на числото в регистри 3 # $4:$5 на числото в регистър $6. 4 5 .ent udiv128 # http://codereview.stackexchange.com/questions/67962 6 .global udiv128 7 udiv128: # q = a_lo<<1;(r = a_hi;)//няма нужда от отделни q, r 8 0000 00054FFE DSRL32 $9,$5,31# /carry = a_lo >> 63; 9 0004 00052878 DSLL $5,$5,1 #_/ 10 0008 24080040 LI $8,64 #брч 11 000c 00041FFE L1: DSRL32 $3,$4,31# temp = r >> 63; 12 0010 00042078 DSLL $4,$4,1 # r = r << 1 13 0014 00892025 OR $4,$4,$9# | carry; 14 0018 00604825 MOVE $9,$3 # carry = temp; 15 001c 15200005 00000000 BNE $9,$0,L2# if (carry == 0) { 16 0024 0086082B 14200003 00000000 BLTU $4,$6,L3# if (r < b) goto shift; 17 0030 65290001 DADDIU $9,$9,1 # carry++; 18 0034 0086202F L2: DSUBU $4,$4,$6# } r -= b; 19 0038 00051FFE L3: DSRL32 $3,$5,31#shift: temp = q >> 63; 20 003c 00052878 DSLL $5,$5,1 # q = q << 1 21 0040 00A92825 OR $5,$5,$9# | carry; 22 0044 00604825 MOVE $9,$3 # carry = temp; 23 0048 6508FFFF DADDIU $8,$8,-1#Следваща 24 004c 1500FFEF 00000000 BNE $8,$0,L1#итерация 25 0054 FCE40000 SD $4,0($7)# *rem = r; 26 MOVE $2,$5 # return q; 27 0058 03E00008 00A01025 JR $31 28 .end udiv128 RISC-V LISTING udiv128.s page 1 1 # Да се напише подпрограма, която да връща в регистър a0 частното, а на адрес, 2 # подаден в регистър a3, да записва остатъка от деленето на числото в регистри 3 # a1:a0 на числото в регистър a2. 4 5 .global udiv128 # http://codereview.stackexchange.com/questions/67962 6 udiv128: # q = a_lo<<1;(r = a_hi;)//няма нужда от отделни q, r 7 0000 9357F503 SRLI a5,a0,63# /carry = a_lo >> 63; 8 0004 13151500 SLLI a0,a0,1 #_/ 9 0008 13070004 LI a4,64 #брч 10 000c 13D8F503 L1: SRLI a6,a1,63# temp = r >> 63; 11 0010 93951500 SLLI a1,a1,1 # r = r << 1 12 0014 B3E5F500 OR a1,a1,a5# | carry; 13 0018 93070800 MV a5,a6 # carry = temp; 14 001c 63960700 BNEZ a5,L2 # if (carry == 0) { 15 0020 63E6C500 BLTU a1,a2,L3# if (r < b) goto shift; 16 0024 93871700 ADDI a5,a5,1 # carry++; 17 0028 B385C540 L2: SUB a1,a1,a2# } r -= b; 18 002c 1358F503 L3: SRLI a6,a0,63#shift: temp = q >> 63; 19 0030 13151500 SLLI a0,a0,1 # q = q << 1 20 0034 3365F500 OR a0,a0,a5# | carry; 21 0038 93070800 MV a5,a6 # carry = temp; 22 003c 1307F7FF ADDI a4,a4,-1#Следваща 23 0040 E31607FC BNEZ a4,L1 #итерация 24 0044 23B0B600 SD a1,0(a3)# *rem = r; 25 0048 67800000 RET # return q; LOONGARCH64 GAS udiv128.s page 1 1 # Да се напише подпрограма, която да връща в регистър $r4 частното, а на адрес, 2 # подаден в регистър $r7, да записва остатъка от деленето на числото в регистри 3 # $r5:$r4 на числото в регистър $r6. 4 5 .global udiv128 # http://codereview.stackexchange.com/questions/67962 6 udiv128: # q = a_lo<<1;(r = a_hi;)//няма нужда от отделни q, r 7 0000 89FC4500 SRLI.D $r9,$r4,63#/carry = a_lo >> 63; 8 0004 84044100 SLLI.D $r4,$r4,1#_| 9 0008 08008103 ORI $r8,$r0,64#брч 10 000c AAFC4500 L1: SRLI.D $r10,$r5,63# temp = r >> 63; 11 0010 A5044100 SLLI.D $r5,$r5,1 # r = r << 1 12 0014 A5241500 OR $r5,$r5,$r9# | carry; 13 0018 49011500 OR $r9,$r10,$r0# carry = temp; 14 001c 200D0044 BNEZ $r9,L2 # if (carry == 0) { 15 0020 A60C0068 BLTU $r5,$r6,L3# if (r < b) goto shift; 16 0024 2905C002 ADDI.D $r9,$r9,1 # carry++; 17 0028 A5981100 L2: SUB.D $r5,$r5,$r6# } r -= b; 18 002c 8AFC4500 L3: SRLI.D $r10,$r4,63#shift:temp = q >> 63; 19 0030 84044100 SLLI.D $r4,$r4,1 # q = q << 1 20 0034 84241500 OR $r4,$r4,$r9# | carry; 21 0038 49011500 OR $r9,$r10,$r0# carry = temp; 22 003c 08FDFF02 ADDI.D $r8,$r8,-1#Следваща 23 0040 1FCDFF47 BNEZ $r8,L1 #итерация 24 0044 E500C029 ST.D $r5,$r7,0 # *rem = r; 25 0048 2000004C JIRL $r0,$r1,0 # return q; # Да се напише подпрограма, която да връща в регистър $0 частното, а на адрес, # подаден в регистър $19, ако той е ненулев, да записва остатъка от деленето udiv128.o: file format ecoff-littlealpha # на числото в регистри $17:$16 на числото в регистър $18. Disassembly of section .text: .ent udiv128 # http://codereview.stackexchange.com/questions/67962 .globl udiv128 0000000000000000 : udiv128: # q = a_lo<<1;(r = a_hi;)//няма нужда от отделни q, r 0: 82 f6 07 4a srl a0,0x3f,t1 srl $16,63,$2 #/carry = a_lo >> 63; 4: 00 04 10 42 addq a0,a0,v0 sll $16,1,$0#_/ 8: 40 00 3f 20 lda t0,64(zero) lda $1,64($31)#брч c: 83 f6 27 4a srl a1,0x3f,t2 L1: srl $17,63,$3 # temp = r >> 63; 10: 11 04 31 42 addq a1,a1,a1 sll $17,1,$17 # r = r << 1 14: 11 04 22 46 or a1,t1,a1 bis $17,$2,$17# | carry; 18: 02 04 7f 44 or t2,zero,t1 bis $3,$31,$2 # carry = temp; 1c: 03 00 40 f4 bne t1,2c bne $2,L2 # if (carry == 0) { 20: a4 03 32 42 cmpult a1,a2,t3 cmpult $17,$18,$4# if (r < b) 24: 02 00 80 f4 bne t3,30 bne $4,L3 # goto shift; 28: 02 34 40 40 addq t1,0x1,t1 addq $2,1,$2 # carry++; 2c: 31 05 32 42 subq a1,a2,a1 L2: subq $17,$18,$17# } r -= b; 30: 83 f6 07 48 srl v0,0x3f,t2 L3: srl $0,63,$3 #shift:temp = q >> 63; 34: 00 04 00 40 addq v0,v0,v0 sll $0,1,$0 # q = q << 1 38: 21 35 20 40 subq t0,0x1,t0 bis $0,$2,$0 # | carry; 3c: 00 04 02 44 or v0,t1,v0 bis $3,$31,$2 # carry = temp; 40: 02 04 7f 44 or t2,zero,t1 subq $1,1,$1 #Следваща 44: f1 ff 3f f4 bne t0,c bne $1,L1 #итерация 48: 01 00 60 e6 beq a3,50 beq $19,L4 #Нулев адрес? Прескочи записа 4c: 00 00 33 b6 stq a1,0(a3) stq $17,0($19)# *rem = r; 50: 01 80 fa 6b ret zero,(ra),0x1 L4: ret # return q; 54: 1f 04 ff 47 nop .end udiv128 58: 00 00 fe 2f unop 5c: 1f 04 ff 47 nop GAS for MMIX udiv128.s page 1 1 % Да се напише подпрограма, която да връща в регистър $0 частното, а на адрес, 2 % подаден в $2, да записва остатъка от деленето на 128-битовото число, чийто 3 % адрес е подаден в регистър $0, на числото в регистър $1. 4 5 .global udiv128 6 udiv128: 7 0000 8F030000 LDOU $3,$0,0 % Старша половина на делимото 8 0004 F6010003 PUT rD,$3 9 0008 8F000008 LDOU $0,$0,8 % rD:$0 = делимо, $1 = делител 10 000c 1E000001 DIVU $0,$0,$1 % $0 = rD:$0 / $1, rR = остатък 11 0010 FE010006 GET $1,rR 12 0014 AF010200 STOU $1,$2,0 % Запиши остатъка 13 0018 C6020202 XOR $2,$2,$2 % Нулирай старшата дума на делимото, защото 14 001c F6010002 PUT rD,$2 % кодът, генериран от компилатора, очаква там 0 15 0020 F8010000 POP 1,0 % Върни частното в $0 HPPA64 LISTING udiv128.s page 1 1 ; Да се напише подпрограма, която да връща в регистър %R28 частното, а на 2 ; адрес, подаден в регистър %R23, ако той е ненулев, да записва остатъка от 3 ; деленето на числото в регистри %R26:%R25 на числото в регистър %R24. 4 5 .global udiv128 ; http://codereview.stackexchange.com/questions/67962 6 udiv128: 7 0000 E8000030 B L3 ; q = a_lo << 1; carry = a_lo >> 63; (след „LDI“) 8 0004 34010082 LDI 65,%R1 ; Брч (r = a_hi;)//няма нужда от отделни q и r 9 0008 0B5A873A L1: ADD,DC,*NUV %R26,%R26,%R26;temp = r>>63; r = r<<1 | carry; carry=temp; 10 000c E800000A B,N L2 ; if(!carry) { 11 0010 0B58A8A0 CMPCLR,*<<= %R24,%R26,%R0; if (r < b) 12 0014 E800000A B,N L3 ; C = 0 goto shift; 13 0018 0B1A041A L2: SUB %R26,%R24,%R26; C = 1 (carry++;) } r -= b; 14 001c 08000400 SUB %R0,%R0,%R0; Възстанови C 15 0020 AC3FBFC5 L3: ADDIB,*<> -1,%R1,L1;Следваща итерация на цикъла(изпълн.се след „ADD,DC“ 16 0024 0B390739 ADD,DC %R25,%R25,%R25; shift: temp=q>>63; q=q<<1|carry; carry=temp; 17 0028 081728A0 CMPCLR,*= %R23,%R0,%R0;Нулев адрес? Прескочи записа 18 002c 0EFA12C0 STD %R26,0(%R23); *rem = r; 19 0030 E840D000 BVE (%R2) ; return q; 20 0034 0819025C COPY %R25,%R28; Върни q в %R28 (изпълнява се преди „BVE“!) TILE-Gx GAS udiv128.s page 1 1 # Да се напише подпрограма, която да връща в регистър r0 частното, а на адрес, 2 # подаден в регистър r3, ако той е ненулев, да записва остатъка от деленето 3 # на числото в регистри r1:r0 на числото в регистър r2. 4 5 .global udiv128 # http://codereview.stackexchange.com/questions/67962 6 udiv128: # q = a_lo<<1;(r = a_hi;)//няма нужда от отделни q, r 7 0000 003048D1 02F80B30 SHRUI r5,r0,63 #/carry = a_lo >> 63; 8 { SHLI r0,r0,1#_/ 9 0008 00100860 E2070A18 MOVEI r4,64 } #брч 10 L1: { SHRUI r6,r1,63 # temp = r >> 63; 11 0010 46F017E0 20080430 SHLI r1,r1,1 } # r = r << 1 12 { OR r1,r1,r5 # | carry; 13 0018 415004D1 C2F83B28 MOVE r5,r6 } # carry = temp; 14 { BNEZ r5,L2 # if (carry == 0) { 15 0020 47202CD0 A100C017 CMPLTU r7,r1,r2 }# if (r < b) 16 0028 003048D1 E100C017 BNEZ r7,L3 # goto shift; 17 0030 003048D1 A2080818 ADDI r5,r5,1 # carry++; 18 0038 003048D1 20106828 L2: SUB r1,r1,r2 # } r -= b; 19 L3: { SHRUI r6,r0,63 #shift:temp = q >> 63; 20 0040 06F01760 00080430 SHLI r0,r0,1 } # q = q << 1 21 { OR r0,r0,r5 # | carry; 22 0048 005004D1 C2F83B28 MOVE r5,r6 } # carry = temp; 23 0050 00304851 82F80F18 ADDI r4,r4,-1 #Следваща 24 0058 003048D1 9BF8BF17 BNEZT r4,L1 #итерация 25 0060 00304851 61004014 BEQZ r3,L4 #Нулев адрес? Прескочи записа 26 0068 00303C34 00400EDE ST r3,r1 # *rem = r; 27 0070 00304851 E0766A28 L4: JR lr # return q; IA-64 GAS udiv128.s page 1 1 // Да се напише подпрограма, която да връща в регистър r8 частното, а на адрес, 2 // подаден в регистър in3, ако той е ненулев, да записва остатъка от деленето 3 // на числото в регистри in1:in0 на числото в регистър in2. 4 5 .global udiv128 // http://codereview.stackexchange.com/questions/67962 6 udiv128: // q = a_lo<<1;(r = a_hi;)//няма нужда от отделни q, r 7 ALLOC loc0=ar.pfs,4,4,0,0 8 MOV loc1=ar.lc//| 9 SHR.U loc2=in0,63//carry= a_lo >> 63; 10 0000 00202110 80055002 046500C0 E4070152 SHL in0=in0,1//_| 11 MOV ar.lc=63 //брч 64-1 12 L1: SHR.U loc3=in1,63// temp = r >> 63; 13 0010 00000000 01000002 F9FC2900 F00B2A00 SHLADD in1=in1,1,loc2//r = r << 1 | carry; 14 MOV loc2=loc3// carry = temp; 15 0020 02000000 010070F2 87002920 14324180 CMP.EQ p8,p9=r0,r0//p8=1 16 CMP.EQ p6,p7=loc2,r0// if (carry == 0) { 17 0030 0330014E 00218000 001270C0 60021CE0 (p6) CMP.LTU p9,p8=in1,in2// if (r < b) goto shift; 18 (p8) ADDS loc2=1,r0// carry++; 19 (p8) SUB in1=in1,in2// } r -= b; 20 0040 CA488444 0834620A 00004224 14121580 SHR.U loc3=in0,63//shift:temp = q >> 63; 21 SHLADD in0=in0,1,loc2//q = q << 1 | carry; 22 MOV loc2=loc3// carry = temp; 23 0050 02000000 010070F2 83002900 04324180 BR.CLOOP.SPTK L1 //Следваща итерация 24 CMP.EQ p6,p7=in3,r0 // Нулев адрес? Прескочи записа 25 0060 1030014E 00210000 000200A0 C0FFFF48 (p7) ST8 [in3]=in1// *rem = r; 26 MOV r8=in0 // return q; 27 0070 0A308C00 07F80108 8D302300 01000184 MOV ar.lc=loc1 // Възстанови съхранения брояч 28 0080 11000000 01000028 05550080 00008400 BR.RET.SPTK rp E2K GAS udiv128.s page 1 1 ! Да се напише подпрограма, която да връща в регистър r0 частното, а на адрес, 2 ! подаден в регистър r3, да записва остатъка от деленето на числото в регистри 3 ! r1:r0 на числото в регистър r2. 4 5 .global udiv128 ! http://codereview.stackexchange.com/questions/67962 6 udiv128: ! q = a_lo<<1;(r = a_hi;)//няма нужда от отделни q, r 7 { setwd wsz=8,nfx=1! 8 0000 12C00000 000000F0 00000000 10010000 return %ctpr3 } ! 9 { disp %ctpr1,L1 ! 10 shrd %r0,63,%r5 !carry= a_lo >> 63; 11 shld %r0,1,%r0!_! 12 0010 2440001C 85D4801B 80C18019 87D0C005 03000040 40003F00 ord 0,64,%r7 }!брч 13 L1: { shrd %r1,63,%r6! temp = r >> 63; 14 0028 2200200C 86D4811B 81C18119 0000850A 00000000 00003F00 shl_addd %r1,1,%r5,%r1 }! r = r << 1 | carry; 15 { ord 0,%r6,%r5! carry = temp; 16 cmpedb 0,1,%pred1!pred1=0 17 0040 1300002C 8586C005 41C1C021 40C08621 cmpedb %r6,0,%pred0 }! if (carry == 0) { 18 0050 11010104 21828121 00000000 00006004 cmpbdb %r1,%r2,%pred1 ? %pred0! if (r < b) goto shift; 19 { ord 0,1,%r5 ? ~%pred1! carry++; 20 subd %r1,%r2,%r1 ? ~%pred1!} r -= b; 21 0060 2300011C 85C1C005 81828113 86D4801B 00003F00 0000E10D shrd %r0,63,%r6 }!shift:temp = q >> 63; 22 { shl_addd %r0,1,%r5,%r0! q = q << 1 | carry; 23 ord 0,%r6,%r5! carry = temp; 24 subd %r7,1,%r7 25 0078 2400203C 8586C005 80C18019 87C18713 60C18721 0000850A cmpbedb %r7,1,%pred0 } 26 0090 01100000 600400C0 ct %ctpr1 ? ~%pred0!Следваща итерация 27 { std %r1,[%r3]! *rem = r; 28 0098 12100010 200C00C0 81C08327 00000000 ct %ctpr3 } ! return q; S/390x LISTING udiv256.s page 1 1 # Да се напише подпрограма, която да записва по адрес в регисър 2 128-битовото 2 # частно, а по адрес в рег.6 – 128-битовия остатък от деленето на числото с ад- 3 # рес на младшата дума в рег.3 и на старшата в рег.4 на числото с адрес в рег.5 4 5 .global udiv256 # http://codereview.stackexchange.com/questions/67962 6 udiv256: 7 0000 EB7CF010 0024 STMG 7,12,16(15) # Съхрани използваните регистри (LNUX-1007-02) 8 0006 EBBC5000 0004 LMG 11,12,0(5) # b = 11:12, rem = 6 9 000c EB9A4000 0004 LMG 9,10,0(4) 10 0012 EB783000 0004 LMG 7,8,0(3) # a = 9:10:7:8 11 0018 1700 XR 0,0 # CC=0 12 001a A7180081 LHI 1,129 # q = a_lo << 1; carry = a_lo >> 127; 13 001e A7F40018 J L3 # (r = a_hi;)//няма нужда от отделни q и r 14 0022 B98800AA L1: ALCGR 10,10 # temp = r >> 127; r = 15 0026 B9880099 ALCGR 9,9 # r << 1 | carry; carry = temp; 16 002a A734000C BRC 3,L2 # CC=2|3 if (carry == 0) { 17 002e B921009B CLGR 9,11 # if (r < b) 18 0032 A744000E JL L3 # CC=1 goto shift; 19 0036 A7240006 JH L2 # CC=2 carry++; 20 003a B92100AC CLGR 10,12 # Старшите думи са равни – сравни младшите 21 003e A7440008 JL L3 # CC=1 22 0042 B90B00AC L2: SLGR 10,12 # } 23 0046 B989009B SLBGR 9,11 # r -= b; 24 004a A71E0000 CHI 1,0 # Възстанови CC=2 25 004e B9880088 L3: ALCGR 8,8 # shift: temp = q >> 127; q = 26 0052 B9880077 ALCGR 7,7 # q << 1 | carry; carry = temp; 27 0056 A716FFE6 BRCT 1,L1 # Следваща итерация на цикъла 28 005a EB9A6000 0024 STMG 9,10,0(6) # *rem = r; 29 0060 EB782000 0024 STMG 7,8,0(2) # return q; 30 0066 EB7CF010 0004 LMG 7,12,16(15) # Възстанови съхранените регистри 31 006c 07FE0707 BR 14 # и върни управлението AMD64 GAS udiv256.s page 1 1 # Да се напише подпрограма, която да връща в регистри RDX:RAX частното, а на 2 # адрес, подаден в [RSP+8], да записва 128-битовия остатък от деленето на 3 # числото в регистри RCX:RDX:RSI:RDI на числото в регистри R9:R8. 4 5 .intel_syntax noprefix 6 .global udiv256 # http://codereview.stackexchange.com/questions/67962 7 udiv256: 8 0000 4897 XCHG RAX,RDI 9 0002 4887F2 XCHG RDX,RSI #// q = RDX:RAX, r = RCX:RSI 10 0005 48D1E0 SHL RAX,1 # q = a_lo << 1; 11 0008 48D1D2 RCL RDX,1 # carry = a_lo >> 127; 12 000b 4889CF MOV RDI,RCX # r = a_hi; // RDI:RSI 13 000e B9800000 00 MOV ECX,128 #// LOOP изисква броячът да бъде в регистър ECX 14 0013 48D1D6 L1: RCL RSI,1 # temp = r >> 127; r = 15 0016 48D1D7 RCL RDI,1 # r << 1 | carry; carry = temp; 16 0019 720C JC L2 # if (carry == 0) { 17 001b 4939F9 CMP R9,RDI # if (r < b) 18 001e 770E JA L3 # goto shift; 19 0020 7205 JB L2 #// CF = 1 carry++; 20 0022 4939F0 CMP R8,RSI #// Старшите думи са равни – сравни младшите 21 0025 7707 JA L3 22 0027 4C29C6 L2: SUB RSI,R8 # } 23 002a 4C19CF SBB RDI,R9 # r -= b; 24 002d F9 STC #// Възстанови CF 25 002e 48D1D0 L3: RCL RAX,1 # shift: temp = q >> 127; q = 26 0031 48D1D2 RCL RDX,1 # q << 1 | carry; carry = temp; 27 0034 E2DD LOOP L1 #// Повтори 128 пъти 28 0036 488B4C24 08 MOV RCX,[RSP+8] 29 003b 488931 MOV [RCX],RSI # *rem = r; 30 003e 48897908 MOV [RCX+8],RDI 31 0042 C3 RET # return q; AARCH64 GAS udiv256.s page 1 1 // Да се напише подпрограма, която да връща в регистри X1:X0 частното, а на 2 // адрес, подаден в регистър X6, да записва 128-битовия остатък от деленето на 3 // числото в регистри X3:X2:X1:X0 на числото в регистри X5:X4. 4 5 .global udiv256 // http://codereview.stackexchange.com/questions/67962 6 udiv256: 7 0000 27108052 MOV W7,#129 //Не може ADDS W7,WZR,#129: R31 тук е SP, не ZR 8 0004 E7001F2B ADDS W7,W7,WZR //Брч _q = a_lo << 1; carry = a_lo >> 127; 9 0008 0B000014 B L3 //C=0_/(r = a_hi;)//няма нужда от отделни q и r 10 000c 420002BA L1: ADCS X2,X2,X2 // temp = r >> 127; r = 11 0010 630003BA ADCS X3,X3,X3 // r << 1 | carry; carry = temp; 12 0014 A2000054 BCS L2 // if (carry == 0) { 13 0018 7F0005EB CMP X3,X5 // if (r < b) 14 001c C3000054 BLO L3 // C = 0 goto shift; 15 0020 420044FA CCMP X2,X4,#2,EQ // Старшите равни? Сравни младшите (иначе C=1) 16 0024 83000054 BLO L3 // C = 0 __________ carry++; 17 0028 420004EB L2: SUBS X2,X2,X4 // C = 1 / } 18 002c 630005DA SBC X3,X3,X5 // / r -= b; 19 0030 FF031FEB SUBS XZR,XZR,XZR //________/ 20 0034 000000BA L3: ADCS X0,X0,X0 // shift: temp = q >> 127; q = 21 0038 210001BA ADCS X1,X1,X1 // q << 1 | carry; carry = temp; 22 003c E7040051 SUB W7,W7,#1 // Следваща итерация на цикъла? 23 0040 67FEFF35 CBNZ W7,L1 // Да, продължи 24 0044 C20C00A9 STP X2,X3,[X6] // *rem = r; 25 0048 C0035FD6 RET // return q; //Върни q в X1:X0 ARC GAS udiv256.s page 1 1 # Да се напише подпрограма, която да връща в регистри r1:r0 частното, а на 2 # адрес, подаден в регистър r6, да записва 128-битовия остатък от деленето на 3 # числото в регистри r3:r2:r1:r0 на числото в r5:r4. 4 5 .global udiv256 # http://codereview.stackexchange.com/questions/67962 6 udiv256: 7 0000 8A5F 0200 MOVL r7,128 # Брч b = r5:r4, rem = r6 8 0004 6058 4080 ASLL.F r0,r0,1 # __q = a_lo << 1; carry = a_lo >> 127; 9 0008 0159 4180 ADCL.F r1,r1,r1 #___/ (r = a_hi;)//няма нужда от отделни q и r 10 000c 015A 8280 L1: ADCL.F r2,r2,r2 # temp = r >> 127; r = 11 0010 015B C380 ADCL.F r3,r3,r3 # r << 1 | carry; carry = temp; 12 0014 87F7 BLO_S L2 # if (carry == 0) { 13 0016 1B0B 4C01 BRLOL r3,r5,L3 # if (r < b) goto shift; 14 001a 0B0D CC00 BRLOL r5,r3,L2 # ____________ carry++; 15 001e 130A 0C01 BRLOL r2,r4,L3 # Старшите/думи са равни – сравни младшите 16 0022 025A 0281 L2: SUBL.F r2,r2,r4 # / } 17 0026 035B 4301 SBCL r3,r3,r5 # / r -= b; 18 002a 4E5E 3E80 RSUBL.F 0,r6,0 #______/ 19 002e 0158 0080 L3: ADCL.F r0,r0,r0 # shift: temp = q >> 127; q = 20 0032 0159 4180 ADCL.F r1,r1,r1 # q << 1 | carry; carry = temp; 21 0036 8C27 3F0B DBNZ r7,L1 # Нова итерация 22 003a 001E 8700 STL r2,[r6] # STDL не работи! 23 003e 081E C700 STL r3,[r6,8] # *rem = r; 24 0042 E07E J_S [blink] # return q;//Върни q в r1:r0 PPC LISTING udiv256.s page 1 1 # Да се напише подпрограма, която да връща в регистри r3:r4 частното, а на 2 # адрес, подаден в r9, да записва 128-битовия остатък от деленето на числото 3 # в регистри r5:r6:r3:r4 на числото в r7:r8. 4 # 5 .global udiv256 # http://codereview.stackexchange.com/questions/67962 6 udiv256: 7 0000 38000000 li r0,0 # Ще потрябва за проверка на преноса 8 0004 35400081 addic. r10,r0,129#CA=0, 129 итерации 9 0008 7D4903A6 mtctr r10 # ___ q = a_lo << 1; carry = a_lo >> 127; 10 000c 4800003C b L3 #__/ (r = a_hi;)// няма нужда от отделни q и r 11 0010 7CC63114 L1: adde r6,r6,r6# temp = r >> 127; 12 0014 7CA52914 adde r5,r5,r5# r = r << 1 | carry; carry = temp; 13 0018 7D4001D5 addme. r10,r0 #CA-1=? (запази CA) 14 001c 41820020 beq L2 # if (carry == 0) { 15 0020 7C253840 cmpld r5,r7 # if (r < b) 16 0024 7D472810 subfc r10,r7,r5#обн.CA 17 0028 41800020 blt L3 # goto shift; 18 002c 41810010 bgt L2 19 0030 7C264040 cmpld r6,r8 # Старшите думи са равни – сравни младшите 20 0034 7D483010 subfc r10,r8,r6#обн.CA 21 0038 41800010 blt L3 #CA=0 ____ carry++; 22 003c 7CC83010 L2: subfc r6,r8,r6#CA=1 / } 23 0040 7CA72910 subfe r5,r7,r5# / r -= b; 24 0044 7C000010 subfc r0,r0,r0#___/ 25 0048 7C842114 L3: adde r4,r4,r4#shift: temp = q >> 127; 26 004c 7C631914 adde r3,r3,r3# q = q << 1 | carry; carry = temp; 27 0050 4200FFC0 bdnz L1 # Следваща итерация 28 0054 F8A90000 std r5,0(r9)# *rem = r; 29 0058 F8C90008 std r6,8(r9) 30 005c 4E800020 blr # return q;// Върни q в r3:r4 SPARC GAS udiv256.s page 1 1 ! Да се напише подпрограма, която да връща в регистри %o0:%o1 частното, а на 2 ! адрес, подаден в [%sp+2047+176], да записва 128-битовия остатък от деленето 3 ! на числото в регистри %o2:%o3:%o0:%o1 на числото в %o4:%o5. 4 5 .global udiv256 ! http://codereview.stackexchange.com/questions/67962 6 udiv256: 7 0000 9DE3BF50 save %sp,-176,%sp!http://docs.oracle.com/cd/E37838_01/pdf/E61063.pdf 8 0004 E05FA8AF ldx [%fp+2047+176],%l0! rem = %l0 (b = %i4:%i5) 9 0008 A6100000 or %g0,%g0,%l3!carry 10 000c 10800016 ba L4!изп.се след mov q = a_lo << 1; carry = a_lo >> 127; 11 0010 A2102081 mov 129,%l1 !брояч (r = a_hi;)//няма нужда от отделни q и r 12 0014 A936B03F L1: srlx %i2,63,%l4 ! temp = r >> 127; 13 0018 B52EB001 sllx %i2,1,%i2 14 001c A536F03F srlx %i3,63,%l2 15 0020 B4168012 or %i2,%l2,%i2 16 0024 B72EF001 sllx %i3,1,%i3 ! r = r << 1 17 0028 B616C013 or %i3,%l3,%i3 ! | carry; 18 002c A6100014 mov %l4,%l3 ! carry = temp; 19 0030 0ACCC009 brnz %l3,L3 !изпълн.се след cmp if (carry == 0) { 20 0034 80A6801C cmp %i2,%i4 ! if (r < b) 21 0038 0A68000B bcs %xcc,L4 ! goto shift; 22 003c 01000000 nop 23 0040 18680004 bgu %xcc,L2!след cmp, но нищо! 24 0044 80A6C01D cmp %i3,%i5 ! Старшите думи са равни – сравни младшите 25 0048 0A680007 bcs %xcc,L4 26 004c 01000000 nop 27 0050 A604E001 L2: inc %l3 ! carry++; 28 0054 B6A6C01D L3: subcc %i3,%i5,%i3 ! } 29 0058 2A680002 bcs,a %xcc,.+8 30 005c B426A001 dec %i2 31 0060 B426801C sub %i2,%i4,%i2 ! r -= b; 32 0064 A936303F L4: srlx %i0,63,%l4 ! shift: temp = q >> 127; 33 0068 B12E3001 sllx %i0,1,%i0 34 006c A536703F srlx %i1,63,%l2 35 0070 B0160012 or %i0,%l2,%i0 36 0074 B32E7001 sllx %i1,1,%i1 ! q = q << 1 37 0078 B2164013 or %i1,%l3,%i1 ! | carry; 38 007c A6100014 mov %l4,%l3 ! carry = temp; 39 0080 A2246001 sub %l1,1,%l1 ! Следваща итерация на цикъла? 40 0084 0AFC7FE4 brnz,pt %l1,L1 ! Да, продължи 41 0088 01000000 nop 42 008c F4740000 stx %i2,[%l0] 43 0090 F6742008 stx %i3,[%l0+8] ! *rem = r; 44 0094 81CFE008 return %i7+8 ! return q;//Възст. и върни q в %o0:%o1 45 0098 01000000 nop MIPS LISTING udiv256.s page 1 1 # Да се напише подпрограма, която да връща в регистри $2:$3 частното, а на 2 # адрес, подаден в $10, да записва 128-битовия остатък от деленето на числото 3 # в регистри $6:$7:$4:$5 на числото в $8:$9. 4 5 .ent udiv256 # http://codereview.stackexchange.com/questions/67962 6 .global udiv256 7 udiv256: 8 0000 00005825 MOVE $11,$0 #carry 9 LI $2,129 # брояч _q = a_lo << 1; carry = a_lo >> 127; 10 0004 10000017 24020081 B L4 #_/(r = a_hi;)// няма нужда от отделни q и r 11 000c 000667FE L1: DSRL32 $12,$6,31 # temp = r >> 127; 12 0010 00063078 DSLL $6,$6,1 13 0014 00273FFE DROTR32 $7,$7,31 14 0018 7CE60007 DINS $6,$7,0,1 # r = r << 1 15 001c 7D670007 DINS $7,$11,0,1 # | carry; 16 0020 01805825 MOVE $11,$12 # carry = temp; 17 0024 1560000B 00000000 BNE $11,$0,L3 # if (carry == 0) { 18 002c 00C8082B 1420000C 00000000 BLTU $6,$8,L4 # if (r < b) 19 0038 0106082B 14200004 00000000 BGTU $6,$8,L2 # goto shift; 20 0044 00E9082B 14200006 00000000 BLTU $7,$9,L4# Старшите думи са равни – сравни младшите 21 0050 656B0001 L2: DADDIU $11,$11,1 # carry++; 22 0054 00E9182B L3: SLTU $3,$7,$9# заем } 23 0058 00E9382F DSUBU $7,$7,$9 24 005c 00C8302F DSUBU $6,$6,$8 25 0060 00C3302F DSUBU $6,$6,$3 # r -= b; 26 0064 000467FE L4: DSRL32 $12,$4,31 #shift: temp = q >> 127; 27 0068 00042078 DSLL $4,$4,1 28 006c 00252FFE DROTR32 $5,$5,31 29 0070 7CA40007 DINS $4,$5,0,1 # q = q << 1 30 0074 7D650007 DINS $5,$11,0,1 # | carry; 31 0078 01805825 MOVE $11,$12 # carry = temp; 32 007c 6442FFFF DADDIU $2,$2,-1# Следваща 33 0080 1440FFE2 00000000 BNE $2,$0,L1# итерация 34 0088 FD460000 SD $6,0($10) 35 008c FD470008 SD $7,8($10) # *rem = r; 36 0090 00A01825 MOVE $3,$5 37 MOVE $2,$4 38 0094 03E00008 00801025 JR $31 # return q;// Върни q в $2:$3 39 009c 00000000 .end udiv256 RISC-V LISTING udiv256.s page 1 1 # Да се напише подпрограма, която да връща в регистри a1:a0 частното, а на 2 # адрес, подаден в регистър a6, да записва 128-битовия остатък от деленето на 3 # числото в регистри a3:a2:a1:a0 на числото в регистри a5:a4. 4 5 .global udiv256 # http://codereview.stackexchange.com/questions/67962 6 udiv256: 7 0000 93080000 MV a7,x0 #carry 8 0004 13031008 LI t1,129 # брояч _q = a_lo << 1; carry = a_lo >> 127; 9 0008 6F004004 J L4 #_/(r = a_hi;)// няма нужда от отделни q и r 10 000c 93D2F603 L1: SRLI t0,a3,63 # temp = r >> 127; 11 0010 93961600 SLLI a3,a3,1 12 0014 9353F603 SRLI t2,a2,63 13 0018 B3E67600 OR a3,a3,t2 14 001c 13161600 SLLI a2,a2,1 # r = r << 1 15 0020 33661601 OR a2,a2,a7 # | carry; 16 0024 93880200 MV a7,t0 # carry = temp; 17 0028 639A0800 BNEZ a7,L3 # if (carry == 0) { 18 002c 63E0F602 BLTU a3,a5,L4 # if (r < b) 19 0030 63E4D700 BGTU a3,a5,L2 # goto shift; 20 0034 636CE600 BLTU a2,a4,L4# Старшите думи са равни – сравни младшите 21 0038 93881800 L2: ADDI a7,a7,1 # carry++; 22 003c B333E600 L3: SLTU t2,a2,a4# заем } 23 0040 3306E640 SUB a2,a2,a4 24 0044 B386F640 SUB a3,a3,a5 25 0048 B3867640 SUB a3,a3,t2 # r -= b; 26 004c 93D2F503 L4: SRLI t0,a1,63 #shift: temp = q >> 127; 27 0050 93951500 SLLI a1,a1,1 28 0054 9353F503 SRLI t2,a0,63 29 0058 B3E57500 OR a1,a1,t2 30 005c 13151500 SLLI a0,a0,1 # q = q << 1 31 0060 33651501 OR a0,a0,a7 # | carry; 32 0064 93880200 MV a7,t0 # carry = temp; 33 0068 1303F3FF ADDI t1,t1,-1# Следваща 34 006c E31003FA BNEZ t1,L1 # итерация 35 0070 2330C800 SD a2,0(a6) 36 0074 2334D800 SD a3,8(a6) # *rem = r; 37 0078 67800000 RET # return q;// Върни q в a1:a0 LOONGARCH64 GAS udiv256.s page 1 1 # Да се напише подпрограма, която да връща в регистри a1:a0 частното, а на 2 # адрес, подаден в регистър a6, да записва 128-битовия остатък от деленето на 3 # числото в регистри a3:a2:a1:a0 на числото в регистри a5:a4. 4 5 .global udiv256 # http://codereview.stackexchange.com/questions/67962 6 udiv256: 7 0000 0B001500 OR $a7,$r0,$r0 #carry 8 0004 0D048203 ORI $t1,$r0,129#брояч _q = a_lo << 1; carry = a_lo >> 127; 9 0008 00440050 B L4 #_/(r = a_hi;)// няма нужда от отделни q и r 10 000c ECFC4500 L1: SRLI.D $t0,$a3,63 # temp = r >> 127; 11 0010 E7044100 SLLI.D $a3,$a3,1 12 0014 CEFC4500 SRLI.D $t2,$a2,63 13 0018 E7381500 OR $a3,$a3,$t2 14 001c C6044100 SLLI.D $a2,$a2,1 # r = r << 1 15 0020 C62C1500 OR $a2,$a2,$a7 # | carry; 16 0024 8B011500 OR $a7,$t0,$r0 # carry = temp; 17 0028 60150044 BNEZ $a7,L3 # if (carry == 0) { 18 002c E9200068 BLTU $a3,$a5,L4 # if (r < b) 19 0030 27090068 BGTU $a3,$a5,L2 # goto shift; 20 0034 C8180068 BLTU $a2,$a4,L4# Старшите думи са равни – сравни младшите 21 0038 6B05C002 L2: ADDI.D $a7,$a7,1 # carry++; 22 003c CEA01200 L3: SLTU $t2,$a2,$a4#заем } 23 0040 C6A01100 SUB.D $a2,$a2,$a4 24 0044 E7A41100 SUB.D $a3,$a3,$a5 25 0048 E7B81100 SUB.D $a3,$a3,$t2 # r -= b; 26 004c ACFC4500 L4: SRLI.D $t0,$a1,63 #shift: temp = q >> 127; 27 0050 A5044100 SLLI.D $a1,$a1,1 28 0054 8EFC4500 SRLI.D $t2,$a0,63 29 0058 A5381500 OR $a1,$a1,$t2 30 005c 84044100 SLLI.D $a0,$a0,1 # q = q << 1 31 0060 842C1500 OR $a0,$a0,$a7 # | carry; 32 0064 8B011500 OR $a7,$t0,$r0 # carry = temp; 33 0068 ADFDFF02 ADDI.D $t1,$t1,-1#Следваща 34 006c BFA1FF47 BNEZ $t1,L1 # итерация 35 0070 4601C029 ST.D $a2,$a6,0 36 0074 4721C029 ST.D $a3,$a6,8 # *rem = r; 37 0078 2000004C JIRL $r0,$ra,0 # return q;// Върни q в a1:a0 # Да се напише подпрограма, която да записва на адрес, подаден в регистър $16 # частното, а на адрес, подаден в [$30+8], да записва 128-битовия остатък от udiv256.o: file format ecoff-littlealpha # деленето на числото в регистри $20:$19:$18:$17 на числото в [$30+0]:$21. Disassembly of section .text: .ent udiv256 # http://codereview.stackexchange.com/questions/67962 .globl udiv256 0000000000000000 : udiv256: 0: 08 00 5e a4 ldq t1,8(sp) ldq $22,0($30) # a = $20:$19:$18:$17, b = $22:$21 4: 00 00 7f 20 lda t2,0(zero) ldq $2,8($30) #rem 8: 00 00 de a6 ldq t8,0(sp) lda $3,0($31) #carry c: 00 34 f0 47 mov 0x81,v0 bis $31,129,$0# брояч _q = a_lo << 1; carry = a_lo >> 127; 10: 13 00 e0 c3 br 60 br $31,L4 #_/(r = a_hi;)// няма нужда от отделни q и r 14: 84 f6 87 4a srl a4,0x3f,t3 L1: srl $20,63,$4 # temp = r >> 127; 18: 85 f6 67 4a srl a3,0x3f,t4 sll $20,1,$20 1c: 13 04 73 42 addq a3,a3,a3 srl $19,63,$5 20: 14 04 94 42 addq a4,a4,a4 bis $20,$5,$20 24: 13 04 63 46 or a3,t2,a3 sll $19,1,$19 # r = r << 1 28: 03 04 9f 44 or t3,zero,t2 bis $19,$3,$19 # | carry; 2c: 14 04 85 46 or a4,t4,a4 bis $4,$31,$3 # carry = temp; 30: 07 00 60 f4 bne t2,50 bne $3,L3 # if (carry == 0) { 34: a1 03 96 42 cmpult a4,t8,t0 cmpult $20,$22,$1 # if (r < b) 38: 09 00 20 f4 bne t0,60 bne $1,L4 # goto shift; 3c: a1 03 d4 42 cmpult t8,a4,t0 cmpult $22,$20,$1 40: 02 00 20 f4 bne t0,4c bne $1,L2 44: a1 03 75 42 cmpult a3,a5,t0 cmpult $19,$21,$1# Старшите думи са равни – сравни младшите 48: 05 00 20 f4 bne t0,60 bne $1,L4 4c: 03 34 60 40 addq t2,0x1,t2 L2: addq $3,1,$3 # carry++; 50: a1 03 75 42 cmpult a3,a5,t0 L3: cmpult $19,$21,$1# заем } 54: 34 05 96 42 subq a4,t8,a4 subq $19,$21,$19 58: 33 05 75 42 subq a3,a5,a3 subq $20,$22,$20 5c: 34 05 81 42 subq a4,t0,a4 subq $20,$1,$20 # r -= b; 60: 85 f6 27 4a srl a1,0x3f,t4 L4: srl $18,63,$4 #shift: temp = q >> 127; 64: 84 f6 47 4a srl a2,0x3f,t3 sll $18,1,$18 68: 11 04 31 42 addq a1,a1,a1 srl $17,63,$5 6c: 12 04 52 42 addq a2,a2,a2 bis $18,$5,$18 70: 20 35 00 40 subq v0,0x1,v0 sll $17,1,$17 # q = q << 1 74: 11 04 23 46 or a1,t2,a1 bis $17,$3,$17 # | carry; 78: 03 04 9f 44 or t3,zero,t2 bis $4,$31,$3 # carry = temp; 7c: 12 04 45 46 or a2,t4,a2 subq $0,1,$0 # Следваща 80: e4 ff 1f f4 bne v0,14 bne $0,L1 # итерация 84: 00 00 62 b6 stq a3,0(t1) stq $19,0($2) 88: 08 00 82 b6 stq a4,8(t1) stq $20,8($2) # *rem = r; 8c: 00 00 30 b6 stq a1,0(a0) stq $17,0,($16) 90: 08 00 50 b6 stq a2,8(a0) stq $18,8,($16) # return q;// Запиши q по адреса в $16 94: 01 80 fa 6b ret zero,(ra),0x1 ret 98: 1f 04 ff 47 nop .end udiv256 9c: 00 00 fe 2f unop GAS for MMIX udiv256.s page 1 1 % Да се напише подпрограма, която да връща в регистри $1:$0 частното, а на 2 % адрес в $3 да записва 128-битовия остатък от деленето на числото с адрес на 3 % младшата дума в регистър $0 и на старшата в $1 на числото с адрес в $2. 4 5 .global udiv256 % http://codereview.stackexchange.com/questions/67962 6 udiv256: 7 0000 8D0A0100 LDO $10,$1,0 8 0004 8D0B0108 LDO $11,$1,8 9 0008 8D010000 LDO $1,$0,0 10 000c 8D000008 LDO $0,$0,8 11 0010 8D070200 LDO $7,$2,0 12 0014 8D080208 LDO $8,$2,8 % a = $10:$11:$1:$0, b = $7:$8 13 0018 C6090909 XOR $9,$9,$9 %carry 14 001c E3060081 SETL $6,129 % брояч _q = a_lo << 1; carry = a_lo >> 127; 15 0020 F0000014 JMP L4 %_/(r = a_hi;)// няма нужда от отделни q и r 16 0024 3F040A3F L1: SRU $4,$10,63 % temp = r >> 127; 17 0028 3B0A0A01 SLU $10,$10,1 18 002c 3F050B3F SRU $5,$11,63 19 0030 C00A0A05 OR $10,$10,$5 20 0034 3B0B0B01 SLU $11,$11,1 % r = r << 1 21 0038 C00B0B09 OR $11,$11,$9 % | carry; 22 003c C1090400 OR $9,$4,0 % carry = temp; 23 0040 4A090007 BNZ $9,L3 % if (carry == 0) { 24 0044 320C0A07 CMPU $12,$10,$7 % if (r < b) 25 0048 400C000A BN $12,L4 % goto shift; 26 004c 440C0003 BP $12,L2 27 0050 320C0B08 CMPU $12,$11,$8% Старшите думи са равни – сравни младшите 28 0054 400C0007 BN $12,L4 29 0058 23090901 L2: ADDU $9,$9,1 % carry++; 30 005c 320C080B L3: CMPU $12,$8,$11 % заем } 31 0060 610C0C00 CSN $12,$12,0% −1 −> 0 32 0064 260B0B08 SUBU $11,$11,$8 33 0068 260A0A07 SUBU $10,$10,$7 34 006c 260A0A0C SUBU $10,$10,$12 % r -= b; 35 0070 3F04013F L4: SRU $4,$1,63 %shift: temp = q >> 127; 36 0074 3B010101 SLU $1,$1,1 37 0078 3F05003F SRU $5,$0,63 38 007c C0010105 OR $1,$1,$5 39 0080 3B000001 SLU $0,$0,1 % q = q << 1 40 0084 C0000009 OR $0,$0,$9 % | carry; 41 0088 C1090400 OR $9,$4,0 % carry = temp; 42 008c 27060601 SUBU $6,$6,1 % Следваща 43 0090 4B06FFE5 BNZ $6,L1 % итерация 44 0094 AD0A0300 STO $10,$3,0 45 0098 AD0B0308 STO $11,$3,8 % *rem = r; 46 009c F8020000 POP 2,0 % return q; HPPA64 LISTING udiv256.s page 1 1 ; Да се напише подпрограма, която да връща в регистри %R28:%R29 частното, а на 2 ; адрес, подаден в регистър %R20, да записва остатъка от деленето на числото в 3 ; регистри %R24:%R23:%R26:%R25 на числото в регистри %R22:%R21 4 5 .global udiv256 ; http://codereview.stackexchange.com/questions/67962 6 udiv256: 7 0000 E8000048 B L3;(C = 0 след „ADDI“) q = a_lo << 1; carry = a_lo >> 127; 8 0004 B4010102 ADDI 129,%R0,%R1 ;Брч (r = a_hi;)//няма нужда от отделни q и r 9 0008 0AF70737 L1: ADD,DC %R23,%R23,%R23 ; temp = r>>127; r = 10 000c 0B188738 ADD,DC,*NUV %R24,%R24,%R24; r<<1 | carry; carry = temp; 11 0010 E8000012 B,N L2 ; if(carry == 0) { 12 0014 0AB70400 SUB %R23,%R21,%R0 13 0018 0AD89520 SUB,DB,*>>= %R24,%R22,%R0; if (r < b) 14 001c E8000012 B,N L3 ; C = 0 goto shift; 15 0020 0AB70417 L2: SUB %R23,%R21,%R23 ; C = 1 ____________ carry++; 16 0024 0AD80538 SUB,DB %R24,%R22,%R24 ;________ / } 17 0028 08000400 SUB %R0,%R0,%R0 ;________X_____ r -= b; 18 002c 0B390739 L3: ADD,DC %R25,%R25,%R25 ; shift: temp = q >> 127; q = 19 0030 AC3FBFA5 ADDIB,*<> -1,%R1,L1;Следваща итерация на цикъла (изп. се след „ADD,DC“) 20 0034 0B5A073A ADD,DC %R26,%R26,%R26 ; q << 1 | carry; carry = temp; 21 0038 0E9812C0 STD %R24,0(%R20) 22 003c 0E9712D0 STD %R23,8(%R20) ; *rem = r; 23 0040 081A025C COPY %R26,%R28 24 0044 E840D000 BVE (%R2) ; return q; 25 0048 0819025D COPY %R25,%R29 ;Върни q в %R28:%R29 (изпълнява се преди „BVE“) TILE-Gx GAS udiv256.s page 1 1 # Да се напише подпрограма, която да връща в регистри r1:r0 частното, а на 2 # адрес, подаден в регистър r6, да записва 128-битовия остатък от деленето 3 # на числото в регистри r3:r2:r1:r0 на числото в регистри r5:r4. 4 5 .global udiv256 # http://codereview.stackexchange.com/questions/67962 6 udiv256: 7 { MOVE r7,zero #carry 8 0000 C7FF07D1 E40F0400 MOVELI r9,129 }# брояч _q = a_lo << 1; carry = a_lo >> 127; 9 0008 003048D1 06000024 J L4 #_/(r = a_hi;)// няма нужда от отделни q и r 10 L1: { SHRUI r8,r3,63 # temp = r >> 127; 11 0010 C8F017E0 61080430 SHLI r3,r3,1 } 12 0018 00304851 41080230 ROTLI r2,r2,1 13 0020 83000036 00306A28 BFINS r3,r2,0,0 # r = r << 1 14 { BFINS r2,r7,0,0 # | carry; 15 0028 C20100B6 03F93B28 MOVE r7,r8 } # carry = temp; 16 { BNEZ r7,L3 # if (carry == 0) { 17 0030 CA502CD0 E200C017 CMPLTU r10,r3,r5 } # if (r < b) 18 { BNEZ r10,L4 # goto shift; 19 0038 4A312CD0 4301C017 CMPLTU r10,r5,r3 } 20 { BNEZ r10,L2 21 0040 8A402C50 4101C017 CMPLTU r10,r2,r4}# Старшите думи са равни – сравни младшите 22 0048 003048D1 4201C017 BNEZ r10,L4 23 0050 003048D1 E3080818 L2: ADDI r7,r7,1 # carry++; 24 0058 00304851 45201628 L3: CMPLTU r10,r2,r4# заем } 25 { SUB r2,r2,r4 26 0060 824044D1 61286828 SUB r3,r3,r5 } 27 0068 003048D1 61506828 SUB r3,r3,r10 # r -= b; 28 L4: { SHRUI r8,r1,63 #shift: temp = q >> 127; 29 0070 48F017E0 20080430 SHLI r1,r1,1 } 30 0078 00304851 00080230 ROTLI r0,r0,1 31 0080 01000036 00306A28 BFINS r1,r0,0,0 # q = q << 1 32 { BFINS r0,r7,0,0 # | carry; 33 0088 C00100B6 03F93B28 MOVE r7,r8 } # carry = temp; 34 0090 003048D1 24F90F18 ADDI r9,r9,-1# Следваща 35 0098 003048D1 37F9BF17 BNEZT r9,L1 # итерация 36 00a0 00304851 C4100019 ST_ADD r6,r2,8 37 { ST r6,r3 # *rem = r; 38 00a8 00306C34 E06E1EDE JR lr } # return q;// Върни q в r1:r0 IA-64 GAS udiv256.s page 1 1 // Да се напише подпрограма, която да връща в регистри r9:r8 частното, а на 2 // адрес, подаден в регистър in6, да записва 128-битовия остатък от деленето 3 // на числото в регистри in3:in2:in1:in0 на числото в регистри in5:in4. 4 5 .global udiv256 // http://codereview.stackexchange.com/questions/67962 6 udiv256: 7 ALLOC loc0=ar.pfs,7,4,0,0// a = in3:in2:in1:in0, b = in5:in4 8 MOV loc1=ar.lc//стар брояч 9 MOV ar.lc=128-1//нов брояч 10 0000 00382D16 80058002 04650000 F00F2A00 SHR.U loc2=in1,63 // carry = a_lo >> 127; 11 SHRP in1=in1,in0,63 // q = a_lo << 1; 12 SHL in0=in0,1 // (r = a_hi;)// няма нужда от отделни q и r 13 0010 00000000 010090F2 87002920 1402FD56 L1: SHR.U loc3=in3,63 // temp = r >> 127; 14 SHRP in3=in3,in2,63 15 0020 00000000 01000002 F9FC2900 00000400 SHLADD in2=in2,1,loc2 // r = r << 1 | carry; 16 0030 01000000 0100A0F2 8F002960 3412FD56 MOV loc2=loc3 // carry = temp; 17 CMP.EQ p7,p8=loc2,r0 // if (carry == 0) { 18 0040 02108952 10209002 A80042E0 900220E0 (p8) BR L2 19 CMP.LTU p6,p7=in3,in5 // if (r < b) 20 (p7) CMP.EQ p8,p9=in3,in5 21 0050 11000000 01000000 00020004 40000040 (p8) CMP.LTU p6,p7=in2,in4//Ако старшите думи са равни, сравни младшите 22 0060 0B308C4A 07F48118 95127000 00000400 (p6) BR L3 // goto shift; 23 ADD loc2=r0,r0,1 // carry++; 24 0070 10318848 07340000 00020003 40000040 L2: CMP.LTU p6,p7=in2,in4//заем } 25 SUB in2=in2,in4 26 0080 01480100 01200000 00020000 00000400 SUB in3=in3,in5 27 0090 01308848 07342012 910A4060 342A1580 (p6) SUB in3=in3,r0,1 // r -= b; 28 L3: SHR.U loc3=in1,63 //shift:temp = q >> 127; 29 SHRP in1=in1,in0,63 30 00a0 C0188D00 04200000 00020000 00000400 SHLADD in0=in0,1,loc2 // q = q << 1 | carry; 31 00b0 00000000 0100A0F2 87002920 1402FD56 MOV loc2=loc3 // carry = temp; 32 BR.CLOOP.SPTK L1//Следваща итерация 33 00c0 0A008152 10209002 A8004200 00000400 ST8 [in6]=in2,8 34 ST8 [in6]=in3,-8 // *rem = r; 35 00d0 10000000 01000000 000200A0 60FFFF48 MOV r8=in0 36 00e0 0A40884C 9815801F 99322F00 01000184 MOV r9=in1 // return q; 37 MOV ar.lc=loc1//Възстанови съхранения брояч 38 00f0 11480042 00210040 05550080 00008400 BR.RET.SPTK rp E2K GAS udiv256.s page 1 1 ! Да се напише подпрограма, която да връща в регистри r1:r0 частното, а на 2 ! адрес, подаден в регистър r6, да записва 128-битовия остатък от деленето на 3 ! числото в регистри r3:r2:r1:r0 на числото в регистри r5:r4 4 5 .global udiv256 ! http://codereview.stackexchange.com/questions/67962 6 udiv256: 7 { setwd wsz=10,nfx=1 ! a = r3:r2:r1:r0, b = r5:r4 8 0000 12C00000 000000F0 00000000 50010000 return %ctpr3 } 9 { ord 0,128,%r7!брояч 10 shrd %r1,63,%r8 ! carry = a_lo >> 127; 11 0010 3300802C 87D4C005 88D0811B 81D5806D 0000810B 00000000 0000C00F 3F008000 insfd %r0,63 << 6,%r1,%r1 } 12 { scld %r1,1,%r1 ! q = a_lo << 1; 13 0030 1200000C 81C18115 80C18019 00000000 shld %r0,1,%r0 } ! (r = a_hi;)// няма нужда от отделни q и r 14 L1: { shrd %r3,63,%r9 ! temp = r >> 127; 15 0040 2200200C 89D4831B 83D0826D 0000830B 00000000 C00F3F00 insfd %r2,63 << 6,%r3,%r3 } 16 { scld %r3,1,%r3 17 shl_addd %r2,1,%r8,%r2 ! r = r << 1 | carry; 18 ord %r9,0,%r8 ! carry = temp; 19 cmpedb %r9,0,%pred1 ! if (carry == 0) { 20 0058 3540203C 83C18315 82C18219 88C08905 41C08921 0B000040 0000880A 00000000 disp %ctpr1,L2 } 21 0078 01100000 610400C0 ct %ctpr1 ? ~%pred1 22 0080 01010004 20858321 cmpbdb %r3,%r5,%pred0 ! if (r < b) 23 0088 01010004 41858321 cmpedb %r3,%r5,%pred1 24 { cmpbdb %r2,%r4,%pred0 ? %pred1!Старшите думи са равни? Сравни младшите 25 0090 12400104 20848221 08000040 00006104 disp %ctpr1,L3 } 26 00a0 01100000 400400C0 ct %ctpr1 ? %pred0 ! goto shift; 27 00a8 01000004 88C1C005 ord 0,1,%r8 ! carry++; 28 L2: { cmpbdb %r2,%r4,%pred0!заем } 29 subd %r2,%r4,%r2 30 00b0 1300001C 20848221 82848213 83858313 subd %r3,%r5,%r3 } 31 00c0 11000104 83C18313 00000000 00006004 subd %r3,1,%r3 ? %pred0! r -= b; 32 L3: { shrd %r1,63,%r9 !shift: temp = q >> 127; 33 00d0 2200200C 89D4811B 81D0806D 0000810B 00000000 C00F3F00 insfd %r0,63 << 6,%r1,%r1 } 34 { scld %r1,1,%r1 35 shl_addd %r0,1,%r8,%r0 ! q = q << 1 | carry; 36 ord %r9,0,%r8 ! carry = temp; 37 subd %r7,1,%r7 38 cmpbedb %r7,1,%pred0 39 00e8 3640207C 81C18115 80C18019 88C08905 87C18713 60C18721 EBFFFF4F 0000880A disp %ctpr1,L1 } 40 0108 01100000 600400C0 ct %ctpr1 ? ~%pred0!Следваща итерация 41 { std %r2,[%r6+0] 42 std %r3,[%r6+8] ! *rem = r; 43 0110 13100090 200C00C0 82C08627 83C88627 ct %ctpr3 } ! return q;