我试图找到给定三个数字的最小和最大数字。
这是我目前的代码:
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov ecx, [num1]
mov ebx, ecx ; initialize ebx with num1 (smallest so far)
cmp ecx, [num2]
jl check_third_num ; jump if num1 < num2
mov ecx, [num2]
mov ebx, ecx ; update ebx if num2 is smaller
check_third_num:
cmp ecx, [num3]
jl update_smallest ; jump if num2/num1 < num3
mov ecx, [num3]
update_smallest:
mov [smallest], ecx ; store the smallest number found
mov ecx, [num1]
cmp ecx, [num2]
jg check_largest ; jump if num1 > num2
mov ecx, [num2]
check_largest:
cmp ecx, [num3]
jg print_result ; jump if num2/num1 > num3
mov ecx, [num3]
print_result:
mov [largest], ecx ; store the largest number found
; Print the largest number
mov ecx, msg_largest
mov edx, len_largest
mov eax, 4 ; system call number (sys_write)
mov ebx, 1 ; file descriptor (stdout)
int 0x80 ; call kernel
; Print the smallest number
mov ecx, msg_smallest
mov edx, len_smallest
mov eax, 4 ; system call number (sys_write)
mov ebx, 1 ; file descriptor (stdout)
int 0x80 ; call kernel
mov eax, 1
int 80h ; exit
section .data
msg_largest db "The largest digit is: ", 0xA, 0xD
len_largest equ $ - msg_largest
msg_smallest db "The smallest digit is: ", 0xA, 0xD
len_smallest equ $ - msg_smallest
num1 dd '47'
num2 dd '22'
num3 dd '31'
section .bss
largest resb 2
smallest resb 2
我很困惑似乎是什么问题。是在
update_smallest
代码上,还是按照我在 section .data
上声明的方式?我尝试对其进行调整,首先将其转换为 ASCII,但这让我有点困惑,所以我尝试按照我拥有的 pdf 文件中的内容进行操作。我只是尝试模仿它的结构,但是现在我添加了查找最小数字的算法,代码不会打印最小和最低的数字。这就是我试图调整的:
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov ecx, [num1]
mov ebx, ecx ; initialize ebx with num1 (smallest so far)
cmp ecx, [num2]
jl check_third_num ; jump if num1 < num2
mov ecx, [num2]
mov ebx, ecx ; update ebx if num2 is smaller
check_third_num:
cmp ecx, [num3]
jl update_smallest ; jump if num2/num1 < num3
mov ecx, [num3]
update_smallest:
mov [smallest], ecx ; store the smallest number found
mov ecx, [num1]
cmp ecx, [num2]
jg check_largest ; jump if num1 > num2
mov ecx, [num2]
check_largest:
cmp ecx, [num3]
jg print_result ; jump if num2/num1 > num3
mov ecx, [num3]
print_result:
mov [largest], ecx ; store the largest number found
; Print the largest number
mov ecx, msg_largest
mov edx, len_largest
mov eax, 4 ; system call number (sys_write)
mov ebx, 1 ; file descriptor (stdout)
int 0x80 ; call kernel
; Print the smallest number
mov ecx, msg_smallest
mov edx, len_smallest
mov eax, 4 ; system call number (sys_write)
mov ebx, 1 ; file descriptor (stdout)
int 0x80 ; call kernel
mov eax, 1
int 80h ; exit
section .data
msg_largest db "The largest digit is: ", 0xA, 0xD
len_largest equ $ - msg_largest
msg_smallest db "The smallest digit is: ", 0xA, 0xD
len_smallest equ $ - msg_smallest
num1 dd '47'
num2 dd '22'
num3 dd '31'
section .bss
largest resb 2
smallest resb 2
我的第一个代码中似乎有什么问题?
考虑到源代码注释,您似乎不理解以下内容: 指令
db
、dd
等以升序文本顺序将数据存储到内存中。
稍后数据出现在更高地址。
这意味着 num1
的存储方式如下:
内存地址 | 记忆内容 | 评论 |
---|---|---|
|
|
|
|
|
|
|
|
NUL 填充以占据 。 |
|
|
〃 |
现在,当您从
dword
加载带有 mov
的 num1
时,ecx
寄存器的 最低有效字节映射到最小内存地址处的字节(反之亦然)。 这意味着当您比较
dd '47'
与dd '31'
时,您实际上是在比较数字0x00003734
和0x00003133
。
该方案称为 little Endian。
作为中间步骤,我建议您进行 Three
sys_write
系统调用。
一种用于消息前缀,一种用于实际数字字符串,另一种用于尾随换行符。
如果按预期工作(=正确的结果),您可以增加复杂性: 你可以这样预留一些空间
section .data
msg_largest:
db 'The largest number is: '
msg_largest_num:
db ' '
db 0x0A
len_largest equ $ - msg_largest
并将“最大”数字串放在
msg_largest_num
处。
确保仅覆盖两个空白字节。
字符序列 LF+CR (
0x0A, 0x0D
) 非常不寻常:
滑架返回左侧页边距的行程时间比换行前进的时间要长,因此它始终是 CR+LF,反之亦然。
但是,显然您是为 32 位 Linux 或兼容的 ABI 编程。 在类 UNIX 环境中,只需简单的 LF 就足够了,请参阅维基百科上的“换行符” 了解更多信息。