鱼C论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: fish111

汇编每日一练

[复制链接]
发表于 2024-11-29 22:20:53 | 显示全部楼层
fish111 发表于 2024-11-29 22:20
但是这个程序运算结果不正确呀


对于给出的程序进行修正,确保运算结果正确输出。我们将使用 `SHR` 指令小心地提取高位和低位。在某些情况下,`SHR` 可能会有兼容性问题,可以通过其他方式提取高位和低位。以下是经过修正的代码:
.MODEL SMALL
.STACK 100h
.DATA
    prompt1 DB 'Enter first hex digit (0-F): $'
    prompt2 DB 'Enter second hex digit (0-F): $'
    prompt3 DB 'Enter operation character (A-D): $'
    result  DB 'Result: $'

.CODE
START:
    MOV AX, @DATA
    MOV DS, AX

    ; 输入第一个十六进制数X
    LEA DX, prompt1
    MOV AH, 09H
    INT 21H

    MOV AH, 01H
    INT 21H
    SUB AL, '0'
    CMP AL, 9
    JBE SHORT STORE_X
    SUB AL, 7  ; 用于字符 A-F
STORE_X:
    MOV BL, AL ; BL = X

    ; 输入第二个十六进制数Y
    LEA DX, prompt2
    MOV AH, 09H
    INT 21H

    MOV AH, 01H
    INT 21H
    SUB AL, '0'
    CMP AL, 9
    JBE SHORT STORE_Y
    SUB AL, 7  ; 用于字符 A-F
STORE_Y:
    MOV BH, AL ; BH = Y

    ; 输入操作符A-D
    LEA DX, prompt3
    MOV AH, 09H
    INT 21H

    MOV AH, 01H
    INT 21H
    MOV CL, AL

    ; 执行操作
    CMP CL, 'A'
    JE ADD_OPERATION
    CMP CL, 'B'
    JE SUB_OPERATION
    CMP CL, 'C'
    JE MUL_OPERATION
    CMP CL, 'D'
    JE DIV_OPERATION

    ; 无效输入,退出程序
    JMP END_PROGRAM

ADD_OPERATION:
    MOV AL, BL
    ADD AL, BH
    MOV AH, 0  ; 确保上位清零
    JMP DISPLAY_RESULT

SUB_OPERATION:
    MOV AL, BL
    SUB AL, BH
    JAE POSITIVE_DIFF
    NEG AL
POSITIVE_DIFF:
    MOV AH, 0  ; 确保上位清零
    JMP DISPLAY_RESULT

MUL_OPERATION:
    MOV AL, BL
    MUL BH
    ; 结果存储在 AX 中
    JMP DISPLAY_RESULT_AX

DIV_OPERATION:
    MOV AL, BL
    XOR AH, AH
    DIV BH
    MOV AH, 0  ; 确保上位清零
    JMP DISPLAY_RESULT

DISPLAY_RESULT:
    LEA DX, result
    MOV AH, 09H
    INT 21H

    ; 显示结果
    MOV AH, 02H
    MOV DL, AL

    ; 显示高半字节
    MOV AL, DL
    AND AL, 0F0h
    SHR AL, 4
    CALL PRINT_HEX

    ; 显示低半字节
    MOV AL, DL
    AND AL, 0Fh
    CALL PRINT_HEX

    JMP END_PROGRAM

DISPLAY_RESULT_AX:
    LEA DX, result
    MOV AH, 09H
    INT 21H

    ; 显示高字节(AX 的高半字节)
    MOV DL, AH
    AND DL, 0F0h
    SHR DL, 4
    CALL PRINT_HEX

    ; 显示低字节(AX 的低半字节)
    MOV DL, AH
    AND DL, 0Fh
    CALL PRINT_HEX

    ; 显示低字节(AX 的低位)
    MOV DL, AL
    AND DL, 0F0h
    SHR DL, 4
    CALL PRINT_HEX

    MOV DL, AL
    AND DL, 0Fh
    CALL PRINT_HEX

    JMP END_PROGRAM

PRINT_HEX:
    ADD AL, '0'
    CMP AL, '9'
    JBE SHORT PRINT_CHAR
    ADD AL, 7
PRINT_CHAR:
    MOV DL, AL
    MOV AH, 02H
    INT 21H
    RET

END_PROGRAM:
    MOV AH, 4CH
    INT 21H

END START

在这个版本中,我们仔细地将寄存器拆分为高位和低位部分来处理 `MUL` 产生的结果,并在需要的地方正确显示结果。请将这段代码拷贝到您的汇编环境中进行编译和测试。希望这可以解决您所遇到的问题!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-12-6 11:48:50 | 显示全部楼层
本帖最后由 人造人 于 2024-12-6 11:51 编辑
sh-5.2$ ls
main.s        Makefile
sh-5.2$ cat Makefile
LINK.o       = $(LD) $(LDFLAGS)
ASFLAGS     := -g
LDFLAGS     := -dynamic-linker /lib64/ld-linux-x86-64.so.2

all: main

main: main.o

clean:
        $(RM) main main.o
sh-5.2$ cat main.s
    .section    .text
input_num:
    subq    $8, %rsp

    # sys_read
    movq    $0, %rax
    movq    $0, %rdi
    movq    %rsp, %rsi
    movq    $8, %rdx
    syscall

    movzbq  (%rsp), %rax
    movq    %rax, %rdi
    movq    %rax, %rsi
    subq    $'0', %rax
    subq    $'a', %rdi
    addq    $10, %rdi
    cmpq    $'a', %rsi
    cmovnbq %rdi, %rax

    addq    $8, %rsp
    retq

output_num:
    subq    $8, %rsp

    movq    %rax, %rdi
    movq    %rax, %rsi
    addq    $'0', %rax
    addq    $'a', %rdi
    subq    $10, %rdi
    cmpq    $10, %rsi
    cmovnbq %rdi, %rax
    movb    %al, (%rsp)
    movb    $'\n', 1(%rsp)

    # sys_write
    movq    $1, %rax
    movq    $1, %rdi
    movq    %rsp, %rsi
    movq    $2, %rdx
    syscall

    addq    $8, %rsp
    retq

    .global     _start
_start:
    callq   input_num
    movq    %rax, %r12
    callq   input_num
    movq    %rax, %r13
    callq   input_num
    movq    %rax, %r8

    movq    %r12, %rax
    xorq    %rdx, %rdx
    divq    %r13
    movq    %rax, %rdi

    movq    %r12, %rax
    mulq    %r13
    movq    %rax, %rsi

    movq    %r12, %rdx
    subq    %r13, %rdx
    movq    %rdx, %rax
    negq    %rax
    movq    $0x8000000000000000, %rcx
    testq   %rcx, %rdx
    cmovnzq %rax, %rdx

    movq    %r12, %rax
    addq    %r13, %rax

    cmpq    $11, %r8
    cmoveq  %rdx, %rax
    cmpq    $12, %r8
    cmoveq  %rsi, %rax
    cmpq    $13, %r8
    cmoveq  %rdi, %rax

    callq   output_num

    # sys_exit
0:  movq    $60, %rax
    xorq    %rdi, %rdi
    syscall
    jmp     0b
sh-5.2$ make
as -g  -o main.o main.s
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 main.o   -o main
sh-5.2$ ls
main  main.o  main.s  Makefile
sh-5.2$ ./main
5
6
a
b
sh-5.2$ ./main
b
3
b
8
sh-5.2$ ./main
3
b
b
8
sh-5.2$ ./main
5
c
b
7
sh-5.2$ ./main
3
4
c
c
sh-5.2$ ./main
c
5
d
2
sh-5.2$
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-21 21:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表