assembly - 在汇编语言中查找奇数和偶数的总和
问题描述
123456789
我有一个任务是通过条件跳转找到偶数和奇数的总和。偶数之和存储在 AX 中,奇数之和存储在 BX 寄存器中。
我将使用两个数组来解决这个问题。
2,4,6,8
1,3,5,7,9
第一个数组的和将以十六进制格式保存在 AX 中,第二个数组保存在 BX 中。
问题是我是汇编语言的初学者,不知道有条件跳转来解决这个问题。谁能帮我以简单的方式解决这个任务?
[org 0x0100]
jmp start
message: db '123456789' ; string to be printed
length: dw 20 ; length of string
clrscr: push es
push ax
push cx
push di
mov ax, 0xb800
mov es, ax ; point es to video base
xor di, di ; point di to top left column
mov ax, 0x0720 ; space char in normal attribute
mov cx, 2000 ; number of screen locations
cld ; auto increment mode
repstosw ; clear the whole screen
pop di
pop cx
pop ax
pop es
ret
; subroutine to print a string
; takes the x position, y position, attribute, address of string and
; its length as parameters
printstr: push bp
mov bp, sp
push es
push ax
push cx
push si
push di
mov ax, 0xb800
mov es, ax ; point es to video base
mov al, 80 ; load al with columns per row
mul byte [bp+10] ; multiply with y position
add ax, [bp+12] ; add x position
shl ax, 1 ; turn into byte offset
mov di,ax ; point di to required location
mov si, [bp+6] ; point si to string
mov cx, [bp+4] ; load length of string in cx
mov ah, [bp+8] ; load attribute in ah
cld ; auto increment mode
nextchar: lodsb ; load next char in al
stosw ; print char/attribute pair
loopnextchar ; repeat for the whole string
pop di
pop si
pop cx
pop ax
pop es
pop bp
ret 10
start: call clrscr ; call the clrscr subroutine
mov ax, 10
push ax ; push x position
mov ax, 15
push ax ; push y position
mov ax, 0x12 ; blue on black attribute
push ax ; push attribute
mov ax, message
push ax ; push address of message
push word [length] ; push message length
callprintstr ; call the printstr subroutine
mov ax, 0x4c00 ; terminate program
int 0x21
解决方案
如果您考虑数字的二进制形式,您将看到一个模式:最右边的位设置 (=1) 为奇数,而不设置 (=0) 为偶数。当您隔离该位时,您可以“有条件地”将该数字添加到一个或另一个总和中。
主要有两种方法来隔离位和处理它:
使用
AND 1
或TEST 1
获取零标志。如果数字是偶数 (result=0) 则设置它,如果它是奇数 (result=1) 则不设置。使用JZ
或JNZ
处理号码。将数字右移到进位标志并使用
JC
或JNC
(“如果进位设置跳转”或“如果进位未设置跳转”)跳转到适当的例程。
请注意AND
并SHR
更改注册表。我建议将其复制到其他寄存器并在操作后恢复它。TEST
不改变寄存器。
一个例子TEST
:
...
mov cx, 9 ; Count downward from 9 to 1
xor ax, ax ; sum of even numbers
xor bx, bx ; sum of odd numbers
l1: ; Entry point for the loop
test cx, 1 ; Is CX even?
jz l2 ; Yes -> jump to the label l2
add bx, cx
jmp l3 ; Skip the following instruction for even numbers
l2:
add ax, cx
l3:
loop l1 ; Repeat until CX becomes 0
...
推荐阅读
- c++ - SQLBindCol 在 64 位 Windows 上因“无效的字符串或缓冲区长度”而失败
- php - 使用 php 将特定数据打印到网页中
- javascript - 如何在js中选择下拉项目时启用按钮?
- javascript - 如何缩小或强制行中组件之间的高度相等
- database - 我如何从 Joomla DB 中检索网站 URL
- c# - 使用 LINQ 搜索查询
- php - Redis laravel 不发布频道
- javascript - Signalr hub 未正确序列化其方法参数的属性
- php - 循环嵌套 PHP 数组,比父数组短
- python - 相当于 pandas 中的 numpy where 函数