比较nasm中的16位数字会产生错误的结果 [英] Comparing 16 bit numbers in nasm produces wrong results

查看:140
本文介绍了比较nasm中的16位数字会产生错误的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始学习汇编.我正在以32位模式编码nasm.我正在尝试比较用户输入的3个数字并打印最大的数字.但是,如果我只使用resb 2为每个数字保留16位,我似乎无法正确比较数字.但是,当我使用resw 2为数字保留32位时,我确实得到了正确的结果.我不明白为什么这是案子.这是我的代码:

I have just started learning assembly. I am coding nasm in 32 bit mode. I am trying to compare 3 numbers inputted by the user and print the largest number. However, I cannot seem to correctly compare the numbers if I only reserve 16 bits for each number using resb 2. I do, however, get correct results when I reserved 32 bits for the numbers using resw 2. I cannot understand why this is the case. Here is my code:

SYS_EXIT equ 1
SYS_WRITE equ 4
SYS_READ equ 3
STD_IN equ 0
STD_OUT equ 1

segment .data

    msg1 db "Enter first number",0xA
    msg1_len equ $- msg1

    msg2 db "Enter second number",0xA
    msg2_len equ $- msg2

    msg3 db "Enter third number",0xA
    msg3_len equ $- msg3

    msg4 db "Largest number is ",0xA
    msg4_len equ $- msg4

segment .bss

    num1 resb 2
    num2 resb 2
    num3 resb 2
    res resb 2

section .text

    global _start

_start:

    mov eax, SYS_WRITE
    mov ebx, STD_OUT
    mov ecx, msg1
    mov edx, msg1_len
    int 0x80

    mov eax, SYS_READ
    mov ebx, STD_IN
    mov ecx, num1
    mov edx, 2
    int 0x80

    mov eax, SYS_WRITE
    mov ebx, STD_OUT
    mov ecx, msg2
    mov edx, msg2_len
    int 0x80

    mov eax, SYS_READ
    mov ebx, STD_IN
    mov ecx, num2
    mov edx, 2
    int 0x80

    mov eax, SYS_WRITE
    mov ebx, STD_OUT
    mov ecx, msg3
    mov edx, msg3_len
    int 0x80

    mov eax, SYS_READ
    mov ebx, STD_IN
    mov ecx, num3
    mov edx, 2
    int 0x80

    mov ecx, [num1]
    cmp ecx, [num2]
    jg check_third
    mov ecx, [num2]


check_third:

    cmp ecx, [num3]
    jg result
    mov ecx, [num3]

result:
    mov [res], ecx
    mov eax, SYS_WRITE
    mov ebx, STD_OUT
    mov ecx, msg4
    mov edx, msg4_len
    int 0x80

    mov eax, SYS_WRITE
    mov ebx, STD_OUT
    mov ecx, res
    mov edx, 2
    int 0x80

exit:
    mov eax, SYS_EXIT
    int 0x80

很抱歉,如果其中包含很多重复代码.我知道为什么当ASCII字符长度只有8位时,为什么需要2个字节来存储键盘输入(因为标准输入还将读取除数字之外的换行符).但是,我对nasm的工作方式一无所知,例如当我将16位内存移至32位寄存器时,nasm会如何反应,如何比较32位和16位值(它将进行带符号扩展还是仅填充)?二进制减法前为0).如果有人可以向我推荐有关nasm技术的资源,除了解释为什么我需要保留2个单词来进行比较,我将不胜感激.

Sorry if it has a lot of repeating code. I understand why I need 2 bytes to store keyboard input when supposedly ascii characters are only 8 bits in length (Since the standard input will also read the new line character aside from the digit). However, I do not know a lot of things about how nasm works such as how it reacts when I move 16 bits of memory to a 32 bit register, how it compares 32 bit and 16 bit values (will it do signed expansion or just pad 0 before binary subtraction). I would truly appreciate it if someone can recommend me resources on the technicalities of nasm aside from explaining why I need to reserve 2 words to do the comparison.

推荐答案

Nasm不会像其他汇编程序一样在标签上保留数据大小的记录.假设您输入1、2和3.那么存储在标签上的字节将是:

Nasm does not keep record of the size of the data at label like some other assemblers. Suppose you enter 1, 2 and 3. Bytes stored at your labels will then be:

num1: db 0x31, 0x0A
num2: db 0x32, 0x0A
num3: db 0x33, 0x0A

当您从标签num1中移出32位数据时,实际上您也在从num2中移出数据.因为小字节序的机器先存储最低有效字节,所以您会得到以下信息:

When you move 32 bits of data from label num1, you are actually also moving data from num2. Because little endian machines store least significant bytes first, you get something like:

    mov ecx, 0x0A320A31 ; high bytes contain num2 and low bytes contain num1
    cmp ecx, 0x0A330A32 ; high bytes contain num3 and low bytes contain num2
    jg check_third
    mov ecx, 0x0A330A32  
check_third:
    cmp ecx, 0x00000A33 ; high bytes contain res and low bytes contain num3
    jg result
    .....

resw 2(或resd 1)将起作用,因为保留内存被初始化为零.如Frank在评论中所述,您应该使用cl而不是ecx,因为在这种情况下,您只需要处理8位即可.

resw 2 (or resd 1) would work because reserved memory is initialized to zeros. As Frank stated in the comment, you should use cl instead of ecx because 8 bits is all you need to handle in this case.

这篇关于比较nasm中的16位数字会产生错误的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆