アセンブリ言語(MIPS)で2点間距離の計算

大学の課題用 (**再　履　修**)

# 整数バージョン

端数は切り捨てます。

## ソースコード

```zsh
# データセクション
.data
	
	# 文字列の定義
	input_message_0: .asciiz "x0: "
	input_message_1: .asciiz "y0: "
	input_message_2: .asciiz "x1: "
	input_message_3: .asciiz "y1: "
	output_message: .asciiz "Distance: "
	eol: .asciiz "\n"


# テキストセクション
.text
	
	# main()
	# 「入力」→「計算」→「出力」を繰り返す
	main:
		
		# x0の要求と代入
		li $v0, 4
		la $a0, input_message_0
		syscall
		li $v0, 5
		syscall
		move $s0, $v0
		
		# y0の要求と代入
		li $v0, 4
		la $a0, input_message_1
		syscall
		li $v0, 5
		syscall
		move $s1, $v0
		
		# x1の要求と代入
		li $v0, 4
		la $a0, input_message_2
		syscall
		li $v0, 5
		syscall
		move $s2, $v0
		
		# y1の要求と代入
		li $v0, 4
		la $a0, input_message_3
		syscall
		li $v0, 5
		syscall
		move $s3, $v0
		
		# 2点間の距離を計算
		sub $t0, $s0, $s2
		sub $t1, $s1, $s3
		mul $t0, $t0, $t0
		mul $t1, $t1, $t1
		add $a0, $t0, $t1
		jal sqrt
		move $t0, $v0
		
		# 答えを表示
		li $v0, 4
		la $a0, output_message
		syscall
		li $v0, 1
		move $a0, $t0
		syscall
		li $v0, 4
		la $a0, eol
		syscall
		syscall
		
		# リトライ
		j main
	
	# sqrt()
	# $a0: in
	# $v0: out
	sqrt:
		
		# r = 0;
		move $v0, $zero
		
		# while (1) {
		sqrt_loop_start:
		
		# a = r * r;
		mul $t0, $v0, $v0
		
		# if (a > x) break;
		bgt $t0, $a0, sqrt_loop_end
		
		# r = r + 1;
		addi $v0, $v0, 1
		
		# }
		j sqrt_loop_start
		sqrt_loop_end:
		
		# r = r - 1;
		addi $v0, $v0, -1
		
		# return r;
		jr $ra
	
```

## 実行例

![ss (2014-05-04 at 03.28.34).png](https://qiita-image-store.s3.amazonaws.com/0/25060/22e09e09-a44d-520c-f9f6-7677d108ca54.png)

# 単精度浮動小数点バージョン

単精度で収束するまで計算します。

## ソースコード

```zsh
# データセクション
.data
	
	# 文字列の定義
	input_message_0: .asciiz "x0: "
	input_message_1: .asciiz "y0: "
	input_message_2: .asciiz "x1: "
	input_message_3: .asciiz "y1: "
	output_message: .asciiz "Distance: "
	eol: .asciiz "\n"
	
	# 浮動小数点数即値の定義
	floats: .float 0.0, 1.0, 2.0
	

# テキストセクション
.text
	
	# main()
	# 「入力」→「計算」→「出力」を繰り返す
	main:
		
		# x0の要求と代入
		li $v0, 4
		la $a0, input_message_0
		syscall
		li $v0, 6
		syscall
		mov.s $f20, $f0
		
		# y0の要求と代入
		li $v0, 4
		la $a0, input_message_1
		syscall
		li $v0, 6
		syscall
		mov.s $f21, $f0
		
		# x1の要求と代入
		li $v0, 4
		la $a0, input_message_2
		syscall
		li $v0, 6
		syscall
		mov.s $f22, $f0
		
		# y1の要求と代入
		li $v0, 4
		la $a0, input_message_3
		syscall
		li $v0, 6
		syscall
		mov.s $f23, $f0
		
		# 0.0, 1.0, 2.0の代入
		la $t0, floats
		l.s $f24, 0($t0)
		l.s $f25, 4($t0)
		l.s $f26, 8($t0)
		
		# 2点間の距離を計算
		sub.s $f4, $f20, $f22
		sub.s $f5, $f21, $f23
		mul.s $f4, $f4, $f4
		mul.s $f5, $f5, $f5
		add.s $f12, $f4, $f5
		jal sqrt
		
		# 答えを表示
		li $v0, 4
		la $a0, output_message
		syscall
		li $v0, 2
		mov.s $f12, $f0
		syscall
		li $v0, 4
		la $a0, eol
		syscall
		syscall
		
		# リトライ
		j main
	
	# sqrt()
	# $f12: in
	# $f0: out
	sqrt:
		
		# if (x <= 0.0) goto sqrt_zero;
		c.le.s $f12, $f24
		bc1t sqrt_zero
		
		# a = 1.0;
		mov.s $f4, $f25
		
		# while (1) {
		sqrt_loop_start:
		
		# b = a
		mov.s $f5, $f4
		
		# a = (x / a + a) / 2
		div.s $f6, $f12, $f4
		add.s $f6, $f6, $f4
		div.s $f4, $f6, $f26
		
		# if (a == b) break;
		c.eq.s $f4, $f5
		bc1t sqrt_loop_end
		
		# }
		j sqrt_loop_start
		sqrt_loop_end:
		
		# return a;
		mov.s $f0, $f4
		jr $ra
		
		# return 0.0;
		sqrt_zero:
		mov.s $f0, $f24
		jr $ra
	
```

## 実行例

![ss (2014-05-04 at 03.31.27).png](https://qiita-image-store.s3.amazonaws.com/0/25060/9b20252e-549d-c4f3-7f2c-585fb68eabe5.png)